Techadamia Backend Documentation

Techadamia Backend - Codebase Structure

Complete directory structure guide with file descriptions and organization.

Tip

Looking for where something lives? The directory tree below is the fast path. For what each function does, see CODE_DOCUMENTATION.md; for how it all fits together, see ARCHITECTURE.md.

Directory Tree

techadamia-backend/
├── cmd/                          # Command-line entry point
│   └── main.go                   # Startup, config validation, server, shutdown
│
├── internal/                     # Internal packages (not importable externally)
│   ├── api/                      # HTTP API layer
│   │   ├── routes.go             # Route definitions, middleware wiring, limiters
│   │   ├── handlers.go           # Core handlers (health, feed, posts, auth, admin, media)
│   │   ├── profile.go            # /me, /me/posts, profile edit, password change, public profiles
│   │   ├── social.go             # Comments, likes, follows, search handlers
│   │   ├── notifications.go      # Notification inbox + the SSE /events stream
│   │   ├── messages.go           # Direct-message handlers
│   │   ├── authflows.go          # Password reset + email verification endpoints
│   │   ├── responses.go          # Response DTOs / row-to-response mapping
│   │   ├── validator.go          # Request validation logic
│   │   ├── main_test.go          # Test harness / shared setup
│   │   ├── admin_test.go         # Admin endpoint tests
│   │   ├── auth_test.go          # Auth/login/CSRF tests
│   │   ├── accountflows_test.go  # Password reset, verification, SSE tests
│   │   ├── feed_test.go          # Feed author/filter/search tests
│   │   ├── media_test.go         # Media upload tests
│   │   ├── messages_test.go      # Messaging tests
│   │   ├── posts_test.go         # Post endpoint tests
│   │   ├── profile_test.go       # Profile + reader-role tests
│   │   └── social_test.go        # Comment/like/follow/notification tests
│   │
│   ├── service/                  # Business logic layer
│   │   ├── services.go           # Service struct, constructor, Notifier wiring
│   │   ├── auth.go               # Login, bootstrap, sessions, password hashing
│   │   ├── users.go              # User management service
│   │   ├── profile.go            # Own profile, public profiles, password change
│   │   ├── tokens.go             # Password-reset + email-verification tokens
│   │   ├── posts.go              # Post management + feed filters + search
│   │   ├── comments.go           # Comment lifecycle + reply notifications
│   │   ├── social.go             # Likes and follows
│   │   ├── notifications.go      # Notification rows + SSE fan-out
│   │   ├── messages.go           # Direct messages
│   │   ├── categories.go         # Category management service
│   │   ├── media.go              # Media handling service
│   │   └── service_test.go       # Service-layer tests
│   │
│   ├── middleware/               # HTTP middleware
│   │   ├── middleware.go         # CORS, rate limit (in-memory), body cap,
│   │   │                         #   security headers, CSRF, auth/role gates
│   │   │                         #   (incl. OptionalAuth for personalization)
│   │   └── ratelimit_redis.go    # Redis-backed rate limiter (Lua INCR/PEXPIRE)
│   │
│   ├── realtime/                 # In-process SSE hub
│   │   └── hub.go                # Per-user subscriber channels, non-blocking publish
│   │
│   ├── mail/                     # Transactional email
│   │   └── mail.go               # SMTP mailer (587 STARTTLS / 465 TLS; dev log mode)
│   │
│   ├── sql/                      # Database layer (mostly SQLC generated)
│   │   ├── db.go                 # Generated DB interface (sqlc)
│   │   ├── models.go             # Generated models + enums (sqlc)
│   │   ├── query.sql             # Hand-written query source
│   │   ├── query.sql.go          # Generated type-safe query functions (sqlc)
│   │   └── schema.sql            # Schema reference for sqlc codegen
│   │
│   ├── utils/                    # Utility functions
│   │   ├── utils.go              # CSV parse, rate-limit spec parse, slug, etc.
│   │   ├── config.go             # Config parsing helpers
│   │   ├── request_id.go         # Request ID context + slog handler
│   │   └── security.go           # CSRF token generation, cookie/header names
│   │
│   └── migrate/                  # Migration runner
│       ├── migrate.go            # Embeds and applies migrations (advisory lock)
│       └── migrations/           # Embedded SQL migration files
│           ├── 000_initial_schema.sql
│           ├── 001_add_deleted_status.sql
│           ├── 002_fix_post_automation_trigger.sql
│           ├── 003_streamline_post_trigger.sql
│           ├── 004_add_reader_role.sql
│           ├── 005_profiles_and_auth_tokens.sql
│           ├── 006_social.sql
│           ├── 007_messages.sql
│           └── 008_post_search.sql
│
├── pkg/                          # Public packages (currently only .gitkeep)
│   └── .gitkeep
│
├── docker-compose.yaml           # Docker Compose configuration
├── Dockerfile                    # Docker image definition
├── .dockerignore                 # Docker build ignore rules
├── Taskfile.yml                  # Task automation (Taskfile)
├── sqlc.yaml                     # SQLC configuration
├── go.mod                        # Go module definition
├── go.sum                        # Go module checksums
├── .env.example                  # Environment variables template
├── .gitignore                    # Git ignore rules
│
├── README.md                     # Project overview and quick start
├── ARCHITECTURE.md               # System design and architecture
├── API_REFERENCE.md              # API endpoint documentation
├── SECURITY.md                   # Security implementation guide
├── DEPLOYMENT.md                 # Deployment instructions
├── DEVELOPMENT.md                # Development guide
├── CODE_DOCUMENTATION.md         # Code reference
├── CODEBASE_STRUCTURE.md         # This document
├── CONTRIBUTING.md               # Contributing guidelines
├── REVIEW_CHECKLIST.md           # Code review checklist
├── IMPLEMENTATION_SUMMARY.md     # Implementation summary
├── DOCUMENTATION_INDEX.md        # Documentation index
│
└── uploads/                      # User media uploads (created at runtime)
    └── [user uploaded files]

Note: generated SQLC files (db.go, models.go, query.sql.go) should not be edited by hand - change query.sql / schema.sql and re-run sqlc generate. internal/sql/ also contains diagram images and a test-data SQL helper.

Core Packages

cmd/ - Application Entry Point

main.go

  • Application startup logic
  • Configuration loading
  • Database connection setup
  • Server initialization
  • Graceful shutdown handling

internal/api/ - HTTP Layer

routes.go

  • Route registration with Gin
  • Middleware setup
  • Route grouping (public, protected, admin)
  • CORS configuration loading

handlers.go

  • Core endpoint handlers (health, feed, posts, register/login, admin, media)
  • Cookie / CSRF token issuance, media upload validation
  • Error handling and PostgreSQL error normalization at the HTTP level

profile.go / social.go / notifications.go / messages.go / authflows.go

  • Feature-grouped handlers: own profile + public profiles; comments, likes, follows, search; notification inbox + the GET /events SSE stream; direct messages; password reset + email verification flows

responses.go

  • Response DTO structs (posts with author/categories/counts, profiles, comments, notifications, conversations, messages, pagination)
  • Mapping from SQLC rows to API response shapes

validator.go

  • Request body validation (register, post, category, comments, messages, profile fields)
  • Field rules (password 8-72, URL-safe username 3-50, 10-digit phone, comment ≤5000 / message ≤2000 chars)
  • Error message generation

internal/service/ - Business Logic

services.go

  • Service struct definitions with dependencies
  • Common service interface patterns
  • Dependency injection setup

auth.go - Authentication Service

  • Login (bcrypt verify, single-session rotation, last_login_at), with a dummy-bcrypt timing mitigation for unknown emails
  • Admin bootstrap (transactional, refuses once an admin exists)
  • Session creation/validation, expired-session cleanup
  • Password hashing with bcrypt (no JWT, no refresh tokens)

users.go - User Service

  • User registration
  • Listing users (all, with post counts) and pending users
  • Status changes, soft delete, and the last-active-admin guard

posts.go - Post Service

  • Post CRUD (transactional create/update with ownership checks; soft delete; archive)
  • Recent feed and fetch-by-slug
  • Category and media association (with validation)

profile.go / tokens.go - Accounts

  • Own profile (GetMe), public profiles, partial profile updates, password change with session rotation
  • Password-reset and email-verification tokens (random 32 bytes; SHA-256 hashes stored; single-use; enumeration-safe resolution)

comments.go / social.go / notifications.go / messages.go - Social layer

  • Comment lifecycle (threading, edit/delete, admin hide) with owner + reply notifications
  • Idempotent likes and follows with notifications
  • Notification rows + fan-outs (new post → followers, pending author → admins, activation → user) pushed over the SSE hub via service.Notifier
  • Direct messages with live push to the recipient

categories.go - Category Service

  • List categories (flat: name + slug)
  • Add a category

media.go - Media Service

  • Persist uploaded-media metadata (storage_key, mime_type, owner)
  • Orphan-media garbage collection (DeleteOrphanMedia, run by startMediaGC; avatars are exempt)

internal/middleware/ - Cross-Cutting Concerns

All middleware lives in two files (there are no separate cors/auth/logging files):

middleware.go

  • CORS allowlist (LoadCORSConfigFromEnv, CORSMiddleware)
  • In-memory fixed-window rate limiter and RateLimitMiddleware
  • MaxBodyBytesMiddleware (global body size cap, /media exempt)
  • SecurityHeadersMiddleware (nosniff, DENY, Referrer/Permissions, optional HSTS/CSP)
  • CSRFMiddleware (double-submit cookie, constant-time compare)
  • RequestIDMiddleware, AccessLogMiddleware
  • Auth/role gates: RequireAuthMiddleware, RequireAuthorMiddleware, RequireAdminMiddleware

ratelimit_redis.go

  • Redis-backed fixed-window limiter using a Lua INCR + PEXPIRE script
  • Selected automatically when RATE_LIMIT_REDIS_URL is set

internal/sql/ - Data Access Layer

db.go, models.go, and query.sql.go are generated by SQLC; do not edit them by hand. Change query.sql / schema.sql and re-run sqlc generate.

query.sql (source)

  • Hand-written SQL queries that SQLC compiles into typed Go functions

schema.sql (source)

  • Table/enum definitions SQLC reads to type the generated code

db.go (SQLC generated)

  • Querier interface, New, WithTx, and the DBTX abstraction

models.go (SQLC generated)

  • User, Post, Category, Media, Session structs
  • Enum types: UserRoleEnum (admin/author), UserStatusEnum (pending/active/suspended/deleted), PostStatusEnum (draft/published/archived)

query.sql.go (SQLC generated)

  • Type-safe query functions for all entities (sessions, users, posts, categories, media)

internal/utils/ - Utility Functions

utils.go

  • CSV parsing (CORS origins, trusted proxies), rate-limit spec parsing, slug generation, and shared helpers

config.go

  • Configuration parsing helpers

request_id.go

  • Request ID context propagation and the slog handler that stamps it on logs

security.go

  • GenerateCSRFToken (32 random bytes, base64url)
  • CSRF cookie/header name constants (csrf_token, X-CSRF-Token)

internal/migrate/ - Migration Runner

Migrations live in internal/migrate/migrations/ and are embedded into the binary (//go:embed). On startup the runner takes a pg_advisory_lock, ensures a schema_migrations tracking table, and applies any unapplied files in name order inside a transaction (files marked -- +no-transaction run outside one). There is no down/rollback support.

Current migration files:

  • 000_initial_schema.sql - initial schema (users, posts, categories, media, sessions, join tables)
  • 001_add_deleted_status.sql - adds the deleted user status
  • 002_fix_post_automation_trigger.sql - fixes a post automation trigger

migrate.go

  • Embeds the migration files, acquires the advisory lock, tracks applied versions, and applies pending migrations in order

File Naming Conventions

Go Files

service_type.go     # Service implementations (auth.go, users.go)
handler_type.go     # Handler implementations (if needed)
middleware_type.go  # Middleware implementations
_test.go            # Test files (parallel structure)

SQL Files

NNN_description.sql # Numbered migrations (000_, 001_, 002_, ... applied in order)
query.sql           # SQLC query definitions
schema.sql          # Schema reference for SQLC codegen

Configuration Files

.env                 # Environment variables (gitignored)
.env.example         # Template for environment variables
docker-compose.yaml  # Local development container config
Dockerfile           # Production container image
sqlc.yaml            # SQLC code generation config

Documentation Files

README.md                   # Project overview
ARCHITECTURE.md             # System design
API_REFERENCE.md            # API documentation
CODEBASE_STRUCTURE.md       # This file
CODE_DOCUMENTATION.md       # Code reference
DEVELOPMENT.md              # Development guide
SECURITY.md                 # Security guidelines
DEPLOYMENT.md               # Deployment guide
CONTRIBUTING.md             # Contributing guidelines
REVIEW_CHECKLIST.md         # Code review checklist
IMPLEMENTATION_SUMMARY.md   # Implementation overview
DOCUMENTATION_INDEX.md      # Documentation index

Code Organization Principles

1. Package by Feature (Not by Layer)

❌ Avoid:

handlers/
  user_handler.go
  post_handler.go
services/
  user_service.go
  post_service.go

✅ Prefer:

internal/
  service/
    users.go      # User service
    posts.go      # Post service
  middleware/
    auth.go

2. Internal vs Public

  • internal/ - Private packages (not importable from outside)
  • pkg/ - Public packages (can be imported as a library)
  • cmd/ - Executable entry points

3. Dependency Direction

api/ (handlers)
  ↓ depends on
service/ (business logic)
  ↓ depends on
sql/ (data access)
  ↓ depends on
Database

Higher layers depend on lower layers, never the reverse.

4. Test Placement

Tests live in the same package as the code they cover. The API tests are split by feature, and the service layer has a single test file:

internal/api/main_test.go     # Shared test harness / setup
internal/api/auth_test.go     # Auth, login, CSRF
internal/api/admin_test.go    # Admin endpoints
internal/api/media_test.go    # Media upload
internal/api/posts_test.go    # Post endpoints
internal/service/service_test.go  # Service-layer tests

Common File Sizes

File Expected Size Notes
handlers.go 500-1000 LOC All HTTP handlers
services.go 200-400 LOC Service structs
auth.go 300-500 LOC Auth service logic
users.go 400-600 LOC User service logic
posts.go 600-800 LOC Post service logic
routes.go 200-300 LOC Route definitions
query.sql.go Auto-generated Variable size
models.go 500-700 LOC Model definitions

Database Connection Flow

main.go
  ├─ Load configuration
  ├─ Connect to PostgreSQL
  ├─ Run migrations
  ├─ Create pgxpool (connection pool)
  ├─ Initialize services with pool
  ├─ Register routes
  └─ Start HTTP server

Requests
  ├─ Handler receives request
  ├─ Passes to service
  ├─ Service calls database
  ├─ Gets connection from pool
  ├─ Executes query
  ├─ Returns connection to pool
  └─ Returns data to handler

Environment Configuration

Configuration Loading Order:

  1. Load defaults (in code)
  2. Load .env file (if exists)
  3. Load environment variables (override .env)
  4. Validate required config
  5. Set up logging based on ENV

Configuration Locations:

  • .env - Local development (gitignored)
  • docker-compose.yaml - Docker environment
  • CI/CD secrets - Production configuration
  • Environment variables - Runtime override

Key Data Structures

User

type User struct {
    ID       pgtype.UUID
    Email    string
    Username string
    Role     UserRole
    Status   UserStatus
}

Post

type Post struct {
    ID        pgtype.UUID
    UserID    pgtype.UUID
    Title     string
    Slug      string
    Content   string
    Status    PostStatus
    CreatedAt time.Time
}

Session (SQLC generated, simplified)

type Session struct {
    SessionID pgtype.UUID         // the session id is itself a UUID v4
    UserID    pgtype.UUID
    CreatedAt pgtype.Timestamptz
    ExpiresAt pgtype.Timestamptz
}

Media (Medium, SQLC generated, simplified)

type Medium struct {
    MediaID    pgtype.UUID
    UserID     pgtype.UUID
    StorageKey string             // relative filename, not an absolute path
    MimeType   pgtype.Text
    CreatedAt  pgtype.Timestamptz
}

Special Directories

uploads/

  • User-uploaded media files
  • Created on first file upload
  • Organized by user ID or date
  • Should be in .gitignore

Dependency Management

All dependencies managed through:

  • go.mod - Module definition
  • go.sum - Module checksums

Key dependencies:

github.com/gin-gonic/gin     - Web framework
github.com/jackc/pgx/v5      - PostgreSQL driver
github.com/redis/go-redis    - Redis client
github.com/joho/godotenv     - .env loading
github.com/google/uuid       - UUID generation
github.com/gosimple/slug     - Slug generation

Build Artifacts

Generated during build:

  • Binary executable (in $GOPATH/bin)
  • Docker image
  • No additional artifacts in repo

Cleanup and Maintenance

Regular Cleanup

  • Remove old log files
  • Clear old session data (handled by cleanup job)
  • Archive old media (future feature)

Code Quality Checks

go fmt ./...      # Format code
go vet ./...      # Check for errors
go test ./...     # Run tests
go mod tidy       # Clean dependencies

Document Version: 1.0 Last Updated: 2026-07-01 Structure Last Reviewed: 2026-05-27

Generated from CODEBASE_STRUCTURE.md on 2026-08-17 23:37 CEST. Edit the Markdown source and re-run task docs to update.