Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions docs/deploystack/development/backend/database.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -96,37 +96,36 @@ This file is automatically managed by the setup API. You typically do not need t

## Database Structure

The database schema is defined in `src/db/schema.ts`. It contains:
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:

1. Base schema tables (core application)
2. Plugin tables (dynamically loaded)
2. Plugin table definitions (populated dynamically)
3. Proper foreign key relationships and constraints

**Important**: Only `schema.sqlite.ts` should be edited for schema changes. The previous `schema.ts` file has been removed to eliminate confusion.

## Making Schema Changes

Follow these steps to add or modify database tables:

1. **Modify Schema Definition**

Edit `src/db/schema.ts` to add or modify tables:
Edit `src/db/schema.sqlite.ts` to add or modify tables:

```typescript
// Example: Adding a new projects table
export const projects = sqliteTable('projects', {
id: text('id').primaryKey(),
name: text('name').notNull(),
description: text('description'),
userId: text('user_id').references(() => users.id),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().default(sql`(strftime('%s', 'now'))`),
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull().default(sql`(strftime('%s', 'now'))`),
userId: text('user_id').references(() => authUser.id),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
});

// Don't forget to add it to baseSchema
export const baseSchema = {
users,
projects, // Add your new table here
};
```

**Note**: Tables are automatically exported and available - no need to manually add them to a base schema object.

2. **Generate Migration**

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

## Development Workflow

1. Make schema changes in `src/db/schema.ts`
1. Make schema changes in `src/db/schema.sqlite.ts`
2. Generate migrations with `npm run db:generate`
3. Restart the server to apply migrations
4. Update application code to use the modified schema
Expand All @@ -193,7 +192,7 @@ Tables defined by plugins are automatically created when the plugin is loaded an
- Include proper foreign key constraints for relational data
- Add explicit types for all columns
- Always use migrations for schema changes in development and production
- **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
- **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
- Never manually create migration files - always use `npm run db:generate` to ensure proper migration structure

## Inspecting the Database
Expand Down
100 changes: 100 additions & 0 deletions docs/deploystack/development/backend/roles.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ When a user registers:
- Automatic conflict resolution for duplicate slugs
- Team owner becomes `team_admin` automatically

#### Default Team Protection

- **Default Team Identification**: Teams created during user registration (name matches username)
- **Name Protection**: Default team names cannot be changed via API or UI
- **Deletion Protection**: Default teams cannot be deleted
- **Description Editing**: Default team descriptions can still be modified
- **UI Indicators**: Frontend shows lock icons and explanatory text for protected fields

#### Team Roles

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

#### Get Team by ID

```http
GET /api/teams/:id
Authorization: Required (teams.view permission)
```

**Response:**

```json
{
"success": true,
"data": {
"id": "team123",
"name": "My Team",
"slug": "my-team",
"description": "Team description",
"owner_id": "user123",
"created_at": "2025-01-30T15:00:00.000Z",
"updated_at": "2025-01-30T15:00:00.000Z"
}
}
```

#### Get Team Members

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

// Get team by ID
const team = await TeamService.getTeamById(teamId);

// Update team
const updatedTeam = await TeamService.updateTeam(teamId, {
name: 'New Name',
description: 'New description'
});

// Delete team
const deleted = await TeamService.deleteTeam(teamId);

// Check team limits
const canCreate = await TeamService.canUserCreateTeam(userId);

// Team membership checks
const isAdmin = await TeamService.isTeamAdmin(teamId, userId);
const isOwner = await TeamService.isTeamOwner(teamId, userId);
const isMember = await TeamService.isTeamMember(teamId, userId);

// Default team checks
const isDefault = await TeamService.isDefaultTeam(teamId, userId);

// Get team membership details
const membership = await TeamService.getTeamMembership(teamId, userId);
```

### Frontend Team Management

The system includes a comprehensive team management interface:

#### Teams List Page (`/teams`)

- Displays all user's teams in a data table
- Shows team name, description, creation date, and member count
- Includes "Manage" button for team administrators
- Uses shadcn/ui components for consistent styling

#### Team Management Page (`/teams/manage/:id`)

- **URL Pattern**: `/teams/manage/{teamId}`
- **Access Control**: Only team administrators can access
- **Design**: Matches admin interface styling (`/admin/users/:id`)
- **Features**:
- Team information display (ID, creation date, update date)
- Editable team name (disabled for default teams with lock icon)
- Editable team description (always available)
- Default team badge and explanations
- Danger zone with team deletion (protected for default teams)
- Confirmation modal for team deletion using shadcn dialog

#### UI Components

```typescript
// Team management form validation
const teamSchema = z.object({
name: z.string().min(1, 'Team name is required'),
description: z.string().optional()
});

// Default team protection in UI
const isDefaultTeam = computed(() => {
return team.value?.name === user.value?.username;
});
```

#### Internationalization

Complete i18n support with translation keys:

- `teams.manage.title` - Page title
- `teams.manage.defaultTeam.badge` - Default team indicator
- `teams.manage.form.name.disabled` - Lock explanation
- `teams.manage.dangerZone.title` - Deletion section
- `teams.manage.delete.confirmation` - Confirmation dialog

## Database Schema

### Roles Table
Expand Down
Loading