Quick Start
How It Works
| Component | Purpose | Lifecycle |
|---|---|---|
| Engine | Database connection pool | Cached globally, first call wins |
| Session | Per-request transaction | Created/disposed per API call |
| get_db | FastAPI dependency | Yields session, auto-commits |
| init_db | Table creation | Call once for persistent databases |
Entities
User (users)
Authentication and identity for platform access.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
name | str | — | Username (unique) |
email | str | — | Email address (unique) |
password_hash | str | — | Hashed password |
created_at | datetime | UTC now | Creation timestamp |
updated_at | datetime | UTC now | Last update timestamp |
Workspace (workspaces)
Top-level container for organizing projects and issues.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
name | str | — | Workspace name |
description | str | None | Optional description |
settings | dict | {} | JSON configuration |
issue_prefix | str | "ISSUE" | Issue numbering prefix |
created_at | datetime | UTC now | Creation timestamp |
updated_at | datetime | UTC now | Last update timestamp |
Member (members)
User membership and roles within workspaces.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
user_id | str | — | Foreign key to users |
workspace_id | str | — | Foreign key to workspaces |
role | str | "member" | Role: owner, admin, member |
created_at | datetime | UTC now | Creation timestamp |
updated_at | datetime | UTC now | Last update timestamp |
Project (projects)
Optional grouping for issues within a workspace.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
workspace_id | str | — | Foreign key to workspaces |
name | str | — | Project name |
description | str | None | Optional description |
settings | dict | {} | JSON configuration |
created_at | datetime | UTC now | Creation timestamp |
updated_at | datetime | UTC now | Last update timestamp |
Issue (issues)
Work items and tasks within a workspace.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
workspace_id | str | — | Foreign key to workspaces |
project_id | str | None | Optional foreign key to projects |
title | str | — | Issue title |
description | str | None | Optional description |
status | str | "backlog" | Status: backlog, in-progress, done |
priority | str | "medium" | Priority: low, medium, high, urgent |
assignee_id | str | None | Optional foreign key to users |
created_by_id | str | None | Optional foreign key to users |
issue_number | int | None | Auto-incrementing number |
created_at | datetime | UTC now | Creation timestamp |
updated_at | datetime | UTC now | Last update timestamp |
Comment (comments)
Discussion threads on issues.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
issue_id | str | — | Foreign key to issues |
author_id | str | None | Optional foreign key to users |
content | str | — | Comment text |
created_at | datetime | UTC now | Creation timestamp |
updated_at | datetime | UTC now | Last update timestamp |
Agent (agents)
AI agents assigned to workspaces.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
workspace_id | str | — | Foreign key to workspaces |
name | str | — | Agent name |
description | str | None | Optional description |
status | str | "idle" | Status: idle, active, error |
config | dict | {} | JSON configuration |
created_at | datetime | UTC now | Creation timestamp |
updated_at | datetime | UTC now | Last update timestamp |
IssueLabel (issue_labels)
Label definitions for categorizing issues.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
workspace_id | str | — | Foreign key to workspaces |
name | str | — | Label name |
color | str | "#000000" | Hex color code |
description | str | None | Optional description |
created_at | datetime | UTC now | Creation timestamp |
updated_at | datetime | UTC now | Last update timestamp |
IssueLabelLink (issue_label_links)
Many-to-many relationship between issues and labels.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
issue_id | str | — | Foreign key to issues |
label_id | str | — | Foreign key to issue_labels |
created_at | datetime | UTC now | Creation timestamp |
IssueDependency (issue_dependencies)
Dependency relationships between issues.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
issue_id | str | — | Foreign key to issues |
depends_on_id | str | — | Foreign key to issues |
dependency_type | str | — | Type: blocks, blocked_by, related |
created_at | datetime | UTC now | Creation timestamp |
ActivityLog (activity_logs)
Audit trail for workspace activities.| Column | Type | Default | Description |
|---|---|---|---|
id | str | UUID | Primary key |
workspace_id | str | — | Foreign key to workspaces |
entity_type | str | — | Entity type: issue, project, workspace |
entity_id | str | — | ID of the affected entity |
action | str | — | Action: created, updated, deleted |
actor_id | str | None | Optional foreign key to users |
details | dict | {} | JSON details |
created_at | datetime | UTC now | Creation timestamp |
Configuration Options
| Name | Where | Default | Description |
|---|---|---|---|
DATABASE_URL | env var | sqlite+aiosqlite:///:memory: | SQLAlchemy async URL used by get_engine() |
get_engine(database_url=None) | praisonai_platform.db | — | Returns the cached AsyncEngine; first call wins, pass database_url to override env |
get_session() | praisonai_platform.db | — | Async generator yielding an AsyncSession per request |
init_db() | praisonai_platform.db | — | Creates all tables via Base.metadata.create_all |
reset_engine() | praisonai_platform.db | — | Disposes and clears the cached engine (tests / URL switch) |
Common Patterns
Running One-Off Queries
Switching to PostgreSQL in Production
Resetting Engine in Tests
Best Practices
Initialize Database Once
Initialize Database Once
For non-memory databases, call
init_db() once at application startup, not per request. The default in-memory SQLite creates tables automatically.Don't Mix Database URLs
Don't Mix Database URLs
The engine is cached globally - if you need to switch
DATABASE_URL values, call reset_engine() first to avoid connection pool conflicts.Keep SQLite for Development Only
Keep SQLite for Development Only
Use SQLite for development and testing, but switch to PostgreSQL for production workloads. SQLite doesn’t handle concurrent writes well in server environments.
Use Sessions Properly
Use Sessions Properly
Always use the
get_db dependency in FastAPI routes - it handles session lifecycle, commits, and rollbacks automatically. Don’t create sessions manually.Related
Workspaces
Manage teams and organize work
Issues
Track and manage work items
Agents
Deploy AI agents to workspaces
Authentication
User authentication and sessions

