Calendar event booking - namthuviec/microservice GitHub Wiki
You can structure a PostgreSQL database table to store calendar event bookings with relevant details. Here's an example schema:
Column Name | Data Type | Description |
---|---|---|
id | SERIAL PRIMARY KEY | Unique identifier for each event |
project_name | VARCHAR(255) | Name of the associated project |
start_date | TIMESTAMP | Event start date and time |
end_date | TIMESTAMP | Event end date and time |
note | TEXT | Additional details about the event |
CREATE TABLE event_bookings (
id SERIAL PRIMARY KEY,
project_name VARCHAR(255) NOT NULL,
start_date TIMESTAMP NOT NULL,
end_date TIMESTAMP NOT NULL,
note TEXT
);
Would you like help with queries to insert, update, or retrieve data from this structure? 🚀
You can create a projects table to store static project data and establish a relationship with the event_bookings
table using a foreign key. Here's how you can structure it in PostgreSQL:
Column Name | Data Type | Description |
---|---|---|
id | SERIAL PRIMARY KEY | Unique identifier for each project |
name | VARCHAR(255) NOT NULL | Name of the project |
description | TEXT | Details about the project |
You'll want to replace project_name
with a foreign key that references the projects
table:
CREATE TABLE projects (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT
);
CREATE TABLE event_bookings (
id SERIAL PRIMARY KEY,
project_id INT NOT NULL,
start_date TIMESTAMP NOT NULL,
end_date TIMESTAMP NOT NULL,
note TEXT,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
);
Now, each event booking is linked to a project by project_id
. Would you like help with inserting data or retrieving it efficiently? 🚀
You can use the React Calendar Library (like react-calendar
or react-big-calendar
) to build an interactive view for your event_bookings while allowing users to filter events by month, week, and day. Here’s how to get started:
Choose the library you want:
npm install react-calendar
npm install react-big-calendar moment
A basic setup using react-calendar
for filtering views:
import React, { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';
const EventCalendar = ({ events }) => {
const [date, setDate] = useState(new Date());
const filteredEvents = events.filter(event =>
new Date(event.start_date).toDateString() === date.toDateString()
);
return (
<div>
<Calendar onChange={setDate} value={date} />
<h3>Events on {date.toDateString()}</h3>
{filteredEvents.map(event => (
<div key={event.id}>
<strong>{event.note}</strong> - {event.start_date}
</div>
))}
</div>
);
};
export default EventCalendar;
For more advanced filtering by month, week, or day, use react-big-calendar
:
import React, { useState } from 'react';
import { Calendar, Views, momentLocalizer } from 'react-big-calendar';
import moment from 'moment';
import 'react-big-calendar/lib/css/react-big-calendar.css';
const localizer = momentLocalizer(moment);
const EventCalendar = ({ events }) => {
const [view, setView] = useState(Views.MONTH);
return (
<div>
<Calendar
localizer={localizer}
events={events}
startAccessor="start_date"
endAccessor="end_date"
views={[Views.MONTH, Views.WEEK, Views.DAY]}
defaultView={view}
onView={(newView) => setView(newView)}
/>
</div>
);
};
export default EventCalendar;
Modify your component to fetch event data from your Spring Boot API:
import { useEffect, useState } from 'react';
const fetchEvents = async () => {
const response = await fetch('http://localhost:8080/api/events');
const data = await response.json();
return data.map(event => ({
...event,
start_date: new Date(event.start_date),
end_date: new Date(event.end_date),
}));
};
useEffect(() => {
fetchEvents().then(setEvents);
}, []);
Start your Spring Boot backend and React frontend, then test event filtering by switching between month, week, and day views.
Would you like to add features like event creation, editing, or color-coded event types? 🚀
jhipster setup a application event_bookings, project type monolithic, database postgress, authenticate JWT, Generate Sprint Boot REST APIs, create JPA repositories, Frontend UI components ReactJS, Multi tenant, multi language
You're looking to set up a JHipster application with EventBookings and Projects, using a monolithic architecture, PostgreSQL, JWT authentication, Spring Boot REST APIs, JPA repositories, a ReactJS frontend, multi-tenancy, and multi-language support. Let’s break it down step by step 🚀.
First, install JHipster:
npm install -g generator-jhipster
Create your new application:
mkdir event-booking-app && cd event-booking-app
jhipster
During the interactive setup, choose:
-
Application type:
Monolithic
-
Database:
PostgreSQL
-
Authentication:
JWT
-
Frontend framework:
React
- Multi-language: ✅ (Select the languages you need)
- Multi-tenancy: ✅ (Choose schema-based or row-based)
JHipster will generate your backend and frontend automatically! 🚀
Use JHipster's entity generator to create them.
jhipster entity Project
Define fields:
-
id
(Auto-generated) -
name
(String
, required) -
description
(Text
)
jhipster entity EventBooking
Define fields:
-
id
(Auto-generated) -
startDate
(Instant
) -
endDate
(Instant
) -
note
(Text
) -
project
(Many-to-One
relationship toProject
)
JHipster will generate Spring Boot REST APIs, JPA repositories, and React UI components!
JHipster does not support multi-tenancy out of the box, so you need to add tenant-based filtering.
Modify your application.yml
:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/{tenantDb}
Each tenant gets its own schema dynamically.
Modify your entities:
@Entity
@Table(name = "projects")
public class Project {
@Column(nullable = false)
private String tenantId; // Each tenant gets its own data
}
Modify repositories to filter by tenant:
@Repository
public interface ProjectRepository extends JpaRepository<Project, Long> {
List<Project> findByTenantId(String tenantId);
}
Modify TokenProvider.java to store tenant ID:
public class CustomTokenProvider extends TokenProvider {
@Override
public String createToken(Authentication authentication) {
String tenantId = getTenantFromUser(authentication);
return Jwts.builder()
.setSubject(authentication.getName())
.claim("tenantId", tenantId)
.signWith(SignatureAlgorithm.HS512, secretKey)
.compact();
}
}
This ensures each tenant gets a unique token.
Modify i18n configuration in src/main/webapp/i18n
.
import { useTranslation } from "react-i18next";
const MyComponent = () => {
const { t } = useTranslation();
return <h1>{t("welcome_message")}</h1>;
};
Edit src/main/webapp/i18n/en.json
:
{
"welcome_message": "Welcome to Event Booking App!"
}
Add other language JSON files (vi.json
, fr.json
, etc.).
Start the application:
./mvnw
npm start
Now you have multi-tenant, multi-language, React + Spring Boot, and JWT authentication in JHipster! 🚀
Would you like dynamic tenant creation or role-based permissions for event bookings? 😊
jhipster setup a application event_bookings, project type microservice, database postgress, authenticate JWT, Generate Sprint Boot REST APIs, create JPA repositories, Frontend UI components ReactJS, Multi tenant, multi language
Setting up a JHipster microservice application with EventBookings and Projects, using PostgreSQL, JWT authentication, Spring Boot REST APIs, JPA repositories, ReactJS frontend, multi-tenancy, and multi-language support requires multiple steps. Here's a complete setup guide 🚀.
First, install JHipster globally:
npm install -g generator-jhipster
Create your gateway (React frontend + API gateway):
mkdir event-booking-gateway && cd event-booking-gateway
jhipster
-
Application type:
Microservice gateway
-
Database:
PostgreSQL
-
Authentication:
JWT
-
Frontend Framework:
React
- Multi-language support: ✅ (Choose your languages)
- Multi-tenancy: ✅ (Schema-based or row-based)
-
Service Discovery: ✅ (
Consul
orJHipster Registry
)
This will generate a React-based UI along with an API gateway.
Each microservice manages different entities (Projects & EventBookings).
Create the Project microservice:
mkdir project-service && cd project-service
jhipster
Choose:
-
Application type:
Microservice
-
Database:
PostgreSQL
-
Authentication:
JWT
-
Service Discovery:
Consul
orJHipster Registry
Create the EventBooking microservice:
mkdir event-booking-service && cd event-booking-service
jhipster
Follow the same setup process.
Modify Projects and EventBookings to store tenant ID.
@Entity
@Table(name = "projects")
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
@Column(nullable = false)
private String tenantId; // Each tenant's data is separated
}
@Entity
@Table(name = "event_bookings")
public class EventBooking {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Instant startDate;
private Instant endDate;
private String note;
@Column(nullable = false)
private String tenantId;
}
Modify repositories to filter queries by tenant ID:
@Repository
public interface ProjectRepository extends JpaRepository<Project, Long> {
List<Project> findByTenantId(String tenantId);
}
@Repository
public interface EventBookingRepository extends JpaRepository<EventBooking, Long> {
List<EventBooking> findByTenantId(String tenantId);
}
Modify application.yml
to dynamically switch tenants:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/{tenantDb}
Modify TokenProvider.java to store tenantId
:
@Override
public String createToken(Authentication authentication) {
User user = (User) authentication.getPrincipal();
String tenantId = user.getTenantId();
return Jwts.builder()
.setSubject(user.getUsername())
.claim("tenantId", tenantId)
.signWith(SignatureAlgorithm.HS512, secretKey)
.compact();
}
Modify i18n configuration in the gateway-service
.
import { useTranslation } from "react-i18next";
const MyComponent = () => {
const { t } = useTranslation();
return <h1>{t("welcome_message")}</h1>;
};
Edit src/main/webapp/i18n/en.json
:
{
"welcome_message": "Welcome to Event Booking!"
}
Add other language files (vi.json
, fr.json
, etc.).
Start Consul (or JHipster Registry), then run the services:
docker-compose up -d
Start each microservice:
cd project-service && ./mvnw
cd event-booking-service && ./mvnw
cd event-booking-gateway && npm start
Your multi-tenant microservice architecture is live! 🎉
Would you like to automate tenant creation or add role-based permissions? 😊
Adding role-based permissions to your JHipster microservice architecture ensures that different users (e.g., Admin, User, Tenant Owner) have restricted access to specific functionalities. Here’s how you can configure RBAC (Role-Based Access Control) in JHipster:
JHipster uses Spring Security with JWT authentication, so you need to set up roles.
Modify AuthoritiesConstants.java
:
public final class AuthoritiesConstants {
public static final String ADMIN = "ROLE_ADMIN";
public static final String USER = "ROLE_USER";
public static final String TENANT_OWNER = "ROLE_TENANT_OWNER";
}
Now, users can be assigned these roles!
Modify User.java
:
@ManyToMany
@JoinTable(
name = "jhi_user_authority",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "authority_name", referencedColumnName = "name")
)
private Set<Authority> authorities = new HashSet<>();
Restrict Admin, User, and Tenant Owner permissions in SecurityConfiguration.java
:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers("/api/admin/**").hasRole("ADMIN") // Admin Only
.requestMatchers("/api/tenants/**").hasRole("TENANT_OWNER") // Tenant Owner Only
.requestMatchers("/api/events/**").hasAnyRole("USER", "TENANT_OWNER") // General Access
.anyRequest().authenticated()
.and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
}
This ensures only authorized users can access certain endpoints.
Create an Admin API to manage role assignments dynamically:
@RestController
@RequestMapping("/api/admin")
public class RoleController {
@Autowired
private UserRepository userRepository;
@PostMapping("/assign-role")
public ResponseEntity<User> assignRole(@RequestParam String username, @RequestParam String role) {
User user = userRepository.findOneByLogin(username).orElseThrow();
user.getAuthorities().add(new Authority(role));
userRepository.save(user);
return ResponseEntity.ok(user);
}
}
Now, Admin users can assign roles to other users via API.
- Start the backend (
./mvnw
) - Use Postman or cURL to send test requests
✅ Example API calls:
POST /api/admin/assign-role?username=johndoe&role=ROLE_TENANT_OWNER
- Restrict
EventBooking
management to onlyTENANT_OWNER
Would you like dynamic tenant role creation or custom JWT claims for roles? 🚀
Dynamic tenant role creation allows each tenant to manage its own set of roles within your multi-tenant JHipster microservice. This means tenants can create custom roles, assign permissions, and manage users dynamically. Here’s how to implement it:
Each tenant should have its own set of roles. Modify the Authority
entity:
@Entity
@Table(name = "tenant_roles")
public class TenantRole {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String roleName; // Custom role (e.g., "MANAGER", "SUPERVISOR")
@Column(nullable = false)
private String tenantId; // Role belongs to a specific tenant
}
Now, each tenant can define its own roles instead of using the global ones.
Define a service that creates tenant-specific roles:
@Service
public class TenantRoleService {
@Autowired
private TenantRoleRepository roleRepository;
public TenantRole createRole(String roleName, String tenantId) {
TenantRole role = new TenantRole();
role.setRoleName(roleName);
role.setTenantId(tenantId);
return roleRepository.save(role);
}
public List<TenantRole> getRolesByTenant(String tenantId) {
return roleRepository.findByTenantId(tenantId);
}
}
This ensures each tenant only manages its own roles.
Create endpoints for role creation and fetching roles per tenant:
@RestController
@RequestMapping("/api/tenants/{tenantId}/roles")
public class TenantRoleController {
@Autowired
private TenantRoleService roleService;
@PostMapping("/create")
public ResponseEntity<TenantRole> createRole(@PathVariable String tenantId, @RequestParam String roleName) {
TenantRole role = roleService.createRole(roleName, tenantId);
return ResponseEntity.ok(role);
}
@GetMapping
public List<TenantRole> getRoles(@PathVariable String tenantId) {
return roleService.getRolesByTenant(tenantId);
}
}
Now, each tenant can create and manage their own roles dynamically.
Modify SecurityConfiguration.java
to apply tenant-specific permissions:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers("/api/tenants/{tenantId}/roles/create").hasAuthority("TENANT_ADMIN")
.requestMatchers("/api/events/**").hasAnyAuthority("TENANT_USER", "TENANT_MANAGER")
.anyRequest().authenticated()
.and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
}
Now, tenants only access features they have permission for.
Start your microservices and gateway, then test role creation:
✅ Create a Role for a Tenant
POST /api/tenants/TENANT1/roles/create?roleName=SUPERVISOR
✅ Fetch Roles for a Tenant
GET /api/tenants/TENANT1/roles
Now, each tenant has full control over its own role structure! 🚀
Would you like dynamic permissions for API access? 😊
Dynamic permissions for API access allow you to control user roles and permissions at runtime, rather than hardcoding them in your security configuration. This is useful for multi-tenant systems, role-based access control (RBAC), and fine-grained API security.
Modify your TenantRole
entity to support API permissions dynamically:
@Entity
@Table(name = "tenant_roles")
public class TenantRole {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String roleName; // e.g., "MANAGER", "SUPERVISOR"
private String tenantId; // Each role belongs to a tenant
@ElementCollection
private Set<String> allowedEndpoints; // Dynamic permissions per role
}
Now, each tenant role can define which APIs it can access.
Create a REST API so tenants can manage role permissions.
@RestController
@RequestMapping("/api/tenants/{tenantId}/roles")
public class TenantRoleController {
@Autowired
private TenantRoleService roleService;
@PostMapping("/create")
public ResponseEntity<TenantRole> createRole(@PathVariable String tenantId, @RequestParam String roleName) {
TenantRole role = roleService.createRole(roleName, tenantId);
return ResponseEntity.ok(role);
}
@PostMapping("/{roleName}/permissions")
public ResponseEntity<TenantRole> updatePermissions(
@PathVariable String tenantId, @PathVariable String roleName, @RequestBody Set<String> endpoints) {
TenantRole role = roleService.updateRolePermissions(tenantId, roleName, endpoints);
return ResponseEntity.ok(role);
}
}
Now, each tenant can create roles and define API permissions dynamically!
Modify SecurityConfiguration.java
to check permissions dynamically:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Autowired
private TenantRoleRepository roleRepository;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((auth) -> auth
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().access((authentication, context) -> {
String tenantId = TenantContext.getTenantId();
String userRole = getUserRole(authentication);
Set<String> allowedEndpoints = roleRepository.findPermissionsByTenantAndRole(tenantId, userRole);
return allowedEndpoints.contains(context.getRequest().getRequestURI()) ?
new AuthorizationDecision(true) : new AuthorizationDecision(false);
})
);
return http.build();
}
}
Now, API access is checked dynamically based on user role and tenant permissions! 🎯
Start your microservices and gateway, then test role creation and API access:
✅ Create a Role for a Tenant
POST /api/tenants/TENANT1/roles/create?roleName=MANAGER
✅ Assign API Permissions to Role
POST /api/tenants/TENANT1/roles/MANAGER/permissions
Body: ["api/events", "api/projects"]
✅ Ensure Role Can Access Only Assigned APIs
Now, users with MANAGER
role can only access api/events
and api/projects
, and nothing else.
Would you like to integrate custom OAuth2 claims for roles or build an admin UI for role management? 🚀
Integrating custom OAuth2 claims for roles allows you to embed role-based access control (RBAC) directly into your authentication system. This is useful for multi-tenant applications where different tenants may have different roles and permissions.
OAuth2 uses JWT for authentication, so modify your token creation logic to include roles dynamically.
@Override
public String createToken(Authentication authentication) {
User user = (User) authentication.getPrincipal();
String tenantId = user.getTenantId();
Set<String> roles = user.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toSet());
return Jwts.builder()
.setSubject(user.getUsername())
.claim("tenantId", tenantId) // Store Tenant ID
.claim("roles", roles) // Add Roles to JWT Token
.signWith(SignatureAlgorithm.HS512, secretKey)
.compact();
}
Now, every JWT token issued will include roles as a claim.
Modify OAuth2 Resource Server to retrieve roles from the JWT token.
@Override
public Authentication getAuthentication(String token) {
Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
String tenantId = claims.get("tenantId", String.class);
List<String> roles = claims.get("roles", List.class);
TenantContext.setTenantId(tenantId); // Store Tenant ID in Context
List<GrantedAuthority> authorities = roles.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
return new UsernamePasswordAuthenticationToken(claims.getSubject(), null, authorities);
}
This ensures that roles are dynamically assigned based on the token claims.
Modify SecurityConfiguration.java to enforce RBAC dynamically:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((auth) -> auth
.requestMatchers("/api/admin/**").hasAuthority("ROLE_ADMIN")
.requestMatchers("/api/tenants/**").hasAuthority("ROLE_TENANT_OWNER")
.requestMatchers("/api/events/**").hasAnyAuthority("ROLE_USER", "ROLE_TENANT_OWNER")
.anyRequest().authenticated()
.and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
}
Now, API access is controlled dynamically based on roles stored inside JWT.
✅ Generate JWT with Roles
POST /api/authenticate
Response JWT:
{
"tenantId": "TENANT1",
"roles": ["ROLE_USER", "ROLE_TENANT_OWNER"]
}
✅ Access APIs Based on Roles
GET /api/admin # Only accessible to ROLE_ADMIN
GET /api/events # Accessible to ROLE_USER, ROLE_TENANT_OWNER
Would you like to integrate tenant-specific claims or custom permissions per tenant role? 🚀
Setting up custom permissions per tenant role allows each tenant to define and control fine-grained access to their own resources. Here's how to implement tenant-specific permissions dynamically in a JHipster microservice architecture.
Modify the TenantRole
entity to support permissions per role:
@Entity
@Table(name = "tenant_roles")
public class TenantRole {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String roleName; // e.g., "MANAGER", "SUPERVISOR"
@Column(nullable = false)
private String tenantId; // Role belongs to a specific tenant
@ElementCollection
private Set<String> allowedActions; // Dynamic permissions per role
}
Now, each role within a tenant can have a unique set of allowed actions (e.g., "CREATE_EVENT"
, "EDIT_PROJECT"
).
Expose endpoints for tenants to assign role permissions dynamically.
@RestController
@RequestMapping("/api/tenants/{tenantId}/roles")
public class TenantRoleController {
@Autowired
private TenantRoleService roleService;
@PostMapping("/{roleName}/permissions")
public ResponseEntity<TenantRole> updatePermissions(
@PathVariable String tenantId, @PathVariable String roleName, @RequestBody Set<String> actions) {
TenantRole role = roleService.updateRolePermissions(tenantId, roleName, actions);
return ResponseEntity.ok(role);
}
@GetMapping("/{roleName}/permissions")
public ResponseEntity<Set<String>> getRolePermissions(@PathVariable String tenantId, @PathVariable String roleName) {
Set<String> permissions = roleService.getPermissionsForRole(tenantId, roleName);
return ResponseEntity.ok(permissions);
}
}
Now, tenants can update and retrieve permissions dynamically.
Modify SecurityConfiguration.java
to check permissions per role dynamically:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Autowired
private TenantRoleRepository roleRepository;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((auth) -> auth
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().access((authentication, context) -> {
String tenantId = TenantContext.getTenantId();
String userRole = getUserRole(authentication);
Set<String> allowedActions = roleRepository.findPermissionsByTenantAndRole(tenantId, userRole);
return allowedActions.contains(context.getRequest().getRequestURI()) ?
new AuthorizationDecision(true) : new AuthorizationDecision(false);
})
);
return http.build();
}
}
This ensures API access is controlled dynamically based on the user's assigned role and its permissions.
✅ Create a Role for a Tenant
POST /api/tenants/TENANT1/roles/create?roleName=MANAGER
✅ Assign Permissions to Role
POST /api/tenants/TENANT1/roles/MANAGER/permissions
Body: ["CREATE_EVENT", "EDIT_PROJECT"]
✅ Ensure Role Can Access Only Assigned APIs
Now, users with MANAGER
can only create events and edit projects, but not delete users or modify other tenants.
Would you like UI integration for managing roles and permissions? 🚀