Skip to content

sanjivthapasvt/KnowBase

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

111 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

KnowBase

Multi-tenant Team Knowledge Base SaaS

A centralized platform where teams can create, organize, and share internal documentation, processes, guides, and institutional knowledge.


πŸš€ Quick Start

# 1. Clone and configure
cp .env.example .env

# 2. Start with Docker
docker compose up -d

# 3. API is available at
open http://localhost:8000/docs

Local Development (without Docker)

# Create virtual environment
python -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -e ".[dev]"

# Run the server
uvicorn app.main:app --reload

# Run migrations
alembic upgrade head

# Run tests
pytest tests/ -v

πŸ“‚ Project Structure

KnowBase/
β”œβ”€β”€ .env.example              # Environment variables template
β”œβ”€β”€ Dockerfile                # Multi-stage Docker build
β”œβ”€β”€ docker-compose.yml        # API + PostgreSQL + Redis
β”œβ”€β”€ pyproject.toml            # Dependencies + ruff + pytest config
β”œβ”€β”€ alembic.ini               # Alembic config
β”‚
β”œβ”€β”€ alembic/                  # Database migrations
β”‚   β”œβ”€β”€ env.py                # Async migration environment
β”‚   β”œβ”€β”€ script.py.mako        # Migration template
β”‚   └── versions/             # Migration files
β”‚
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ main.py               # FastAPI app factory + lifespan
β”‚   β”œβ”€β”€ dependencies.py       # Shared deps (auth, tenant, RBAC)
β”‚   β”œβ”€β”€ middleware.py          # Request logging, CORS
β”‚   β”‚
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   └── router.py         # Aggregates all module routers
β”‚   β”‚
β”‚   β”œβ”€β”€ core/                 # Infrastructure
β”‚   β”‚   β”œβ”€β”€ config.py         # Pydantic Settings
β”‚   β”‚   β”œβ”€β”€ database.py       # Async SQLAlchemy engine + sessions
β”‚   β”‚   β”œβ”€β”€ redis.py          # Redis connection pool
β”‚   β”‚   β”œβ”€β”€ security.py       # JWT + password hashing
β”‚   β”‚   β”œβ”€β”€ logging.py        # Structured logging
β”‚   β”‚   └── exceptions.py     # Custom exceptions + handlers
β”‚   β”‚
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── base.py           # BaseDBModel (id, created_at, updated_at)
β”‚   β”‚
β”‚   └── modules/              # Domain modules
β”‚       β”œβ”€β”€ auth/             # JWT auth (register, login, refresh)
β”‚       β”œβ”€β”€ users/            # User profiles
β”‚       β”œβ”€β”€ organizations/    # Tenant organizations
β”‚       β”œβ”€β”€ memberships/      # RBAC (user ↔ org roles)
β”‚       β”œβ”€β”€ workspaces/       # Workspaces within orgs
β”‚       β”œβ”€β”€ documents/        # Knowledge base documents
β”‚       β”œβ”€β”€ document_versions/# Version history
β”‚       β”œβ”€β”€ audit_logs/       # Immutable audit trail
β”‚       └── invites/          # Org invitations
β”‚
└── tests/
    β”œβ”€β”€ conftest.py           # Async fixtures
    β”œβ”€β”€ test_health.py        # Health check test
    └── test_auth.py          # Auth flow tests

Each module follows the same internal structure:

modules/{name}/
β”œβ”€β”€ __init__.py
β”œβ”€β”€ models.py       # SQLModel ORM models
β”œβ”€β”€ schemas.py      # Pydantic request/response schemas
β”œβ”€β”€ repository.py   # Data access layer (DB queries)
β”œβ”€β”€ service.py      # Business logic layer
β”œβ”€β”€ router.py       # FastAPI router (API endpoints)
└── dependencies.py # Module-specific dependencies (if needed)

πŸ›οΈ Architecture

Layered Architecture

Request β†’ Router β†’ Service β†’ Repository β†’ Database
                      ↓
                   Schemas (Pydantic)
Layer Responsibility
Router HTTP endpoints, request parsing, response serialization
Service Business logic, validation rules, orchestration
Repository Database queries, data persistence
Models ORM definitions (SQLModel)
Schemas Input/output validation (Pydantic v2)

How Modules Interact

Modules communicate through their service layer, never directly through repositories or models of another module. For example:

  • OrganizationService imports Membership model to create the owner membership on org creation.
  • InviteService accepts dependencies for UserRepository and MembershipRepository to handle invite acceptance.
  • dependencies.py (shared) imports User and Membership models for auth and RBAC checks.

This keeps boundaries clear β€” each module owns its data, and cross-module interactions happen through injected dependencies at the service layer.


πŸ” Auth System

JWT-based authentication with access + refresh token flow:

Token Lifetime Purpose
Access Token 30 minutes API authentication
Refresh Token 7 days Issue new access tokens

Endpoints:

  • POST /api/v1/auth/register β€” Create account, get tokens
  • POST /api/v1/auth/login β€” Login with email/password
  • POST /api/v1/auth/refresh β€” Refresh expired access token

Auth Dependency:

from app.dependencies import get_current_user

@router.get("/protected")
async def protected_endpoint(user: User = Depends(get_current_user)):
    # user is authenticated
    ...

🏒 Multi-Tenancy

Organization-scoped architecture. All tenant data includes an organization_id column.

How it works:

  1. User authenticates β†’ JWT contains user_id
  2. Request includes org_id in the URL path (e.g., /api/v1/organizations/{org_id}/documents)
  3. get_current_org_id dependency verifies the user is a member of that org
  4. All queries are scoped to organization_id
from app.dependencies import get_current_org_id

@router.get("/organizations/{org_id}/documents")
async def list_docs(org_id: UUID = Depends(get_current_org_id)):
    # org_id is validated β€” user is a member
    ...

🧾 RBAC (Role-Based Access Control)

Roles are stored in the memberships table (join between users and organizations):

Role Permissions
owner Full access, manage members, delete org
admin Manage content, invite members, update org
member Create/edit documents, create workspaces
viewer Read-only access

Usage:

from app.dependencies import require_role
from app.modules.memberships.models import RoleEnum

@router.delete("/{doc_id}")
async def delete_doc(
    _role: None = Depends(require_role(RoleEnum.owner, RoleEnum.admin)),
):
    # Only owner and admin can reach here
    ...

βž• How to Add a New Module

  1. Create the module directory:

    app/modules/your_module/
    β”œβ”€β”€ __init__.py
    β”œβ”€β”€ models.py
    β”œβ”€β”€ schemas.py
    β”œβ”€β”€ repository.py
    β”œβ”€β”€ service.py
    └── router.py
    
  2. Define the model in models.py (inherit from BaseDBModel)

  3. Create schemas in schemas.py (Pydantic BaseModel)

  4. Build the repository in repository.py (accept AsyncSession)

  5. Write business logic in service.py (accept repository)

  6. Create the router in router.py with endpoints

  7. Register the router in app/api/router.py:

    from app.modules.your_module.router import router as your_module_router
    api_router.include_router(your_module_router)
  8. Import the model in alembic/env.py for migration autogeneration

  9. Generate migration:

    alembic revision --autogenerate -m "add your_module table"
    alembic upgrade head

βš™οΈ Tech Stack

Technology Purpose
FastAPI Web framework
PostgreSQL Primary database
SQLModel ORM (SQLAlchemy + Pydantic)
Alembic Database migrations
Redis Caching / background jobs readiness
Pydantic v2 Validation & serialization
python-jose JWT tokens
passlib Password hashing (bcrypt)
Docker Containerization
pytest Testing
Ruff Linting & formatting

🐳 Docker

# Start all services
docker compose up -d

# Rebuild after code changes
docker compose up --build

# View logs
docker compose logs -f api

# Stop all services
docker compose down

Services:

  • api β†’ localhost:8000 (FastAPI with hot-reload)
  • postgres β†’ localhost:5432 (PostgreSQL 16)
  • redis β†’ localhost:6379 (Redis 7)

πŸ§ͺ Testing

# Run all tests
pytest tests/ -v

# Run specific test file
pytest tests/test_auth.py -v

# Run with coverage (install pytest-cov first)
pytest tests/ --cov=app --cov-report=term-missing

πŸ“‹ API Endpoints Overview

Method Endpoint Description Auth
POST /api/v1/auth/register Register βœ—
POST /api/v1/auth/login Login βœ—
POST /api/v1/auth/refresh Refresh token βœ—
GET /api/v1/users/me Current user profile βœ“
PATCH /api/v1/users/me Update profile βœ“
POST /api/v1/organizations Create org βœ“
GET /api/v1/organizations List my orgs βœ“
GET /api/v1/organizations/{org_id}/members List members βœ“ (member+)
POST /api/v1/organizations/{org_id}/members Add member βœ“ (admin+)
GET /api/v1/organizations/{org_id}/workspaces List workspaces βœ“
POST /api/v1/organizations/{org_id}/workspaces Create workspace βœ“ (member+)
GET /api/v1/organizations/{org_id}/documents List documents βœ“
POST /api/v1/organizations/{org_id}/documents Create document βœ“ (member+)
GET /api/v1/organizations/{org_id}/documents/{id}/versions List versions βœ“
GET /api/v1/organizations/{org_id}/audit-logs Audit logs βœ“ (admin+)
POST /api/v1/organizations/{org_id}/invites Send invite βœ“ (admin+)
POST /api/v1/invites/accept Accept invite βœ“
GET /health Health check βœ—

About

KnowBase is a multi-tenant centralized platform where teams can create, organize, and share internal documentation, processes, guides, and institutional knowledge.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors