Files
claudia-docs-api/alembic/versions/002_api_tokens.py
Motoko 204badb964 feat: Add role-based API tokens for Claudia Docs
- Add api_tokens table with role-based access (researcher, developer, viewer)
- Add POST /auth/token/generate endpoint for creating tokens
- Add GET /auth/tokens endpoint for listing user's tokens
- Add DELETE /auth/tokens/{token_id} endpoint for revoking tokens
- Add agent_type field to documents (research, development, general)
- Implement role-based access control for documents:
  - researcher: access to research and general documents
  - developer: access to development and general documents
  - viewer: read-only access
- Update document model and schemas with agent_type field
- Add comprehensive tests for API token functionality
- All existing tests pass (73 total)
2026-03-31 01:46:51 +00:00

55 lines
1.6 KiB
Python

"""Add api_tokens table and agent_type column
Revision ID: 002
Revises: 001
Create Date: 2026-03-31
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
revision: str = '002'
down_revision: Union[str, None] = '001'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# Add agent_type column to documents table
op.add_column('documents', sa.Column('agent_type', sa.String(20), sa.TEXT(), nullable=True))
# Set default value for existing documents
op.execute("UPDATE documents SET agent_type = 'general' WHERE agent_type IS NULL")
# Make the column NOT NULL after setting defaults
op.alter_column('documents', 'agent_type', nullable=False)
# Add CHECK constraint for agent_type
op.execute("""
CREATE INDEX IF NOT EXISTS idx_documents_agent_type ON documents(agent_type)
""")
# Create api_tokens table
op.execute("""
CREATE TABLE IF NOT EXISTS api_tokens (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
token_hash TEXT NOT NULL,
role TEXT NOT NULL CHECK (role IN ('researcher', 'developer', 'viewer')),
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT (datetime('now')),
last_used_at TIMESTAMP NULL
)
""")
# Create index for api_tokens
op.execute("CREATE INDEX IF NOT EXISTS idx_api_tokens_agent ON api_tokens(agent_id)")
def downgrade() -> None:
op.drop_table('api_tokens')
op.drop_column('documents', 'agent_type')