Skip to content

Commit fe700a4

Browse files
authored
Merge pull request #153 from deploystackio/feat/dev-docs
docs: update database and roles documentation; add global event bus g…
2 parents b816497 + af99ed4 commit fe700a4

5 files changed

Lines changed: 1022 additions & 14 deletions

File tree

docs/deploystack/development/backend/database.mdx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,37 +96,36 @@ This file is automatically managed by the setup API. You typically do not need t
9696

9797
## Database Structure
9898

99-
The database schema is defined in `src/db/schema.ts`. It contains:
99+
The database schema is defined in `src/db/schema.sqlite.ts`. This is the **single source of truth** for all database schema definitions. It contains:
100100

101101
1. Base schema tables (core application)
102-
2. Plugin tables (dynamically loaded)
102+
2. Plugin table definitions (populated dynamically)
103+
3. Proper foreign key relationships and constraints
104+
105+
**Important**: Only `schema.sqlite.ts` should be edited for schema changes. The previous `schema.ts` file has been removed to eliminate confusion.
103106

104107
## Making Schema Changes
105108

106109
Follow these steps to add or modify database tables:
107110

108111
1. **Modify Schema Definition**
109112

110-
Edit `src/db/schema.ts` to add or modify tables:
113+
Edit `src/db/schema.sqlite.ts` to add or modify tables:
111114

112115
```typescript
113116
// Example: Adding a new projects table
114117
export const projects = sqliteTable('projects', {
115118
id: text('id').primaryKey(),
116119
name: text('name').notNull(),
117120
description: text('description'),
118-
userId: text('user_id').references(() => users.id),
119-
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().default(sql`(strftime('%s', 'now'))`),
120-
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull().default(sql`(strftime('%s', 'now'))`),
121+
userId: text('user_id').references(() => authUser.id),
122+
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
123+
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
121124
});
122-
123-
// Don't forget to add it to baseSchema
124-
export const baseSchema = {
125-
users,
126-
projects, // Add your new table here
127-
};
128125
```
129126

127+
**Note**: Tables are automatically exported and available - no need to manually add them to a base schema object.
128+
130129
2. **Generate Migration**
131130

132131
Run the migration generation command:
@@ -181,7 +180,7 @@ Tables defined by plugins are automatically created when the plugin is loaded an
181180

182181
## Development Workflow
183182

184-
1. Make schema changes in `src/db/schema.ts`
183+
1. Make schema changes in `src/db/schema.sqlite.ts`
185184
2. Generate migrations with `npm run db:generate`
186185
3. Restart the server to apply migrations
187186
4. Update application code to use the modified schema
@@ -193,7 +192,7 @@ Tables defined by plugins are automatically created when the plugin is loaded an
193192
- Include proper foreign key constraints for relational data
194193
- Add explicit types for all columns
195194
- Always use migrations for schema changes in development and production
196-
- **Important**: When adding foreign key relationships, update the dialect-specific schema files (e.g., `src/db/schema.sqlite.ts`) rather than the central `schema.ts` file, as Drizzle Kit uses these files for migration generation
195+
- **Important**: All schema changes should be made in `src/db/schema.sqlite.ts` as it is the single source of truth for Drizzle Kit migration generation
197196
- Never manually create migration files - always use `npm run db:generate` to ensure proper migration structure
198197

199198
## Inspecting the Database

docs/deploystack/development/backend/roles.mdx

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ When a user registers:
129129
- Automatic conflict resolution for duplicate slugs
130130
- Team owner becomes `team_admin` automatically
131131

132+
#### Default Team Protection
133+
134+
- **Default Team Identification**: Teams created during user registration (name matches username)
135+
- **Name Protection**: Default team names cannot be changed via API or UI
136+
- **Deletion Protection**: Default teams cannot be deleted
137+
- **Description Editing**: Default team descriptions can still be modified
138+
- **UI Indicators**: Frontend shows lock icons and explanatory text for protected fields
139+
132140
#### Team Roles
133141

134142
- **Team Admin**: Full control over team settings and management
@@ -195,6 +203,30 @@ DELETE /api/teams/:id
195203
Authorization: Required (teams.delete permission)
196204
```
197205

206+
#### Get Team by ID
207+
208+
```http
209+
GET /api/teams/:id
210+
Authorization: Required (teams.view permission)
211+
```
212+
213+
**Response:**
214+
215+
```json
216+
{
217+
"success": true,
218+
"data": {
219+
"id": "team123",
220+
"name": "My Team",
221+
"slug": "my-team",
222+
"description": "Team description",
223+
"owner_id": "user123",
224+
"created_at": "2025-01-30T15:00:00.000Z",
225+
"updated_at": "2025-01-30T15:00:00.000Z"
226+
}
227+
}
228+
```
229+
198230
#### Get Team Members
199231

200232
```http
@@ -217,14 +249,82 @@ const team = await TeamService.createTeam({
217249
// Get user's teams
218250
const teams = await TeamService.getUserTeams(userId);
219251

252+
// Get team by ID
253+
const team = await TeamService.getTeamById(teamId);
254+
255+
// Update team
256+
const updatedTeam = await TeamService.updateTeam(teamId, {
257+
name: 'New Name',
258+
description: 'New description'
259+
});
260+
261+
// Delete team
262+
const deleted = await TeamService.deleteTeam(teamId);
263+
220264
// Check team limits
221265
const canCreate = await TeamService.canUserCreateTeam(userId);
222266

223267
// Team membership checks
224268
const isAdmin = await TeamService.isTeamAdmin(teamId, userId);
225269
const isOwner = await TeamService.isTeamOwner(teamId, userId);
270+
const isMember = await TeamService.isTeamMember(teamId, userId);
271+
272+
// Default team checks
273+
const isDefault = await TeamService.isDefaultTeam(teamId, userId);
274+
275+
// Get team membership details
276+
const membership = await TeamService.getTeamMembership(teamId, userId);
226277
```
227278

279+
### Frontend Team Management
280+
281+
The system includes a comprehensive team management interface:
282+
283+
#### Teams List Page (`/teams`)
284+
285+
- Displays all user's teams in a data table
286+
- Shows team name, description, creation date, and member count
287+
- Includes "Manage" button for team administrators
288+
- Uses shadcn/ui components for consistent styling
289+
290+
#### Team Management Page (`/teams/manage/:id`)
291+
292+
- **URL Pattern**: `/teams/manage/{teamId}`
293+
- **Access Control**: Only team administrators can access
294+
- **Design**: Matches admin interface styling (`/admin/users/:id`)
295+
- **Features**:
296+
- Team information display (ID, creation date, update date)
297+
- Editable team name (disabled for default teams with lock icon)
298+
- Editable team description (always available)
299+
- Default team badge and explanations
300+
- Danger zone with team deletion (protected for default teams)
301+
- Confirmation modal for team deletion using shadcn dialog
302+
303+
#### UI Components
304+
305+
```typescript
306+
// Team management form validation
307+
const teamSchema = z.object({
308+
name: z.string().min(1, 'Team name is required'),
309+
description: z.string().optional()
310+
});
311+
312+
// Default team protection in UI
313+
const isDefaultTeam = computed(() => {
314+
return team.value?.name === user.value?.username;
315+
});
316+
```
317+
318+
#### Internationalization
319+
320+
Complete i18n support with translation keys:
321+
322+
- `teams.manage.title` - Page title
323+
- `teams.manage.defaultTeam.badge` - Default team indicator
324+
- `teams.manage.form.name.disabled` - Lock explanation
325+
- `teams.manage.dangerZone.title` - Deletion section
326+
- `teams.manage.delete.confirmation` - Confirmation dialog
327+
228328
## Database Schema
229329

230330
### Roles Table

0 commit comments

Comments
 (0)