Files
jason c86b950a0d
Build and Push Docker Image / build (push) Successful in 6s
explainer file
2026-04-22 22:34:52 -05:00

256 lines
9.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CODEDUMP
Internal dashboard for tracking AI tools and coding projects. Provides a high-level overview of what the team is building, what tools are available, and the completion status of active work — all in one place.
---
## Purpose
CODEDUMP gives teams a single place to:
- Track AI tools and coding projects with completion percentages
- Attach markdown documentation and project files
- Link to internal/external URLs and Google Drive sources
- Highlight new tools available to the team
- Manage access via admin accounts and 4-digit user PINs
---
## Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18 + TypeScript + Vite |
| Styling | Tailwind CSS (dark mode, CSS variable theming) |
| Backend | Node.js + Express + TypeScript |
| Database | SQLite via `better-sqlite3` |
| Auth | JWT (12h expiry) + bcryptjs (admin passwords) + HMAC-SHA256 (user PINs) |
| File uploads | Multer (local disk storage) |
| Markdown | `react-markdown` + `remark-gfm` |
| Container | Docker (multi-stage build, single container) |
---
## Project Structure
```
codedump/
├── client/ # React frontend
│ ├── src/
│ │ ├── api/index.ts # Typed fetch wrappers (JWT injected automatically)
│ │ ├── hooks/
│ │ │ ├── useAuth.ts # AuthContext — JWT storage, login/logout
│ │ │ └── useSettings.ts # SettingsContext — branding, accent color
│ │ ├── components/
│ │ │ ├── layout/
│ │ │ │ ├── Layout.tsx # App shell (sidebar + outlet)
│ │ │ │ └── Sidebar.tsx # Nav — auth-aware, admin section, logout
│ │ │ ├── projects/
│ │ │ │ ├── ProjectCard.tsx # Card with progress bar, links, tags
│ │ │ │ └── ProjectForm.tsx # Create/edit form with color picker
│ │ │ ├── tools/
│ │ │ │ └── ToolCard.tsx # Tool card with NEW badge
│ │ │ └── ui/
│ │ │ ├── Badge.tsx # Status/role badges
│ │ │ ├── Button.tsx # Primary/secondary/ghost/danger variants
│ │ │ ├── Modal.tsx # Accessible overlay (Escape to close)
│ │ │ └── ProgressBar.tsx # Accent-colored progress indicator
│ │ ├── pages/
│ │ │ ├── Login.tsx # PIN pad + admin login
│ │ │ ├── Dashboard.tsx # Stats, new tools spotlight, recent projects
│ │ │ ├── Projects.tsx # Filterable project grid
│ │ │ ├── ProjectDetail.tsx # Docs viewer, completion editor, links
│ │ │ ├── Tools.tsx # Tool catalog with search + filter
│ │ │ ├── Settings.tsx # Branding, logo upload, accent color
│ │ │ └── AdminUsers.tsx # User management (admin only)
│ │ └── types/index.ts # Shared TypeScript interfaces
│ ├── index.html
│ ├── vite.config.ts # Dev proxy: /api → localhost:3000
│ ├── tailwind.config.js
│ └── tsconfig.json
├── server/ # Express backend
│ ├── src/
│ │ ├── db/schema.ts # SQLite schema, migrations, admin bootstrap
│ │ ├── lib/pinHash.ts # HMAC-SHA256 PIN hashing (deterministic lookup)
│ │ ├── middleware/auth.ts # requireAuth / requireAdmin JWT guards
│ │ └── routes/
│ │ ├── auth.ts # POST /pin, POST /login, GET /me
│ │ ├── projects.ts # CRUD + tag/category support
│ │ ├── tools.ts # CRUD
│ │ ├── uploads.ts # POST (multer) + DELETE for documents
│ │ ├── settings.ts # GET/PUT settings, POST logo upload
│ │ └── users.ts # Admin-only user CRUD
│ ├── tsconfig.json
│ └── package.json
├── Dockerfile # Multi-stage: client build → server build → runtime
├── docker-compose.yml
├── .dockerignore
├── INSTALL.md # Unraid GUI install guide
└── package.json # npm workspaces root
```
---
## Database Schema
**`users`** — Authentication accounts
| Column | Type | Notes |
|---|---|---|
| `id` | TEXT PK | UUID |
| `username` | TEXT UNIQUE | Display name |
| `role` | TEXT | `admin` or `user` |
| `pin_hash` | TEXT UNIQUE | HMAC-SHA256 of 4-digit PIN (users only) |
| `password_hash` | TEXT | bcrypt hash (admins only) |
| `created_at` | TEXT | ISO datetime |
**`projects`** — Core project records
| Column | Type | Notes |
|---|---|---|
| `id` | TEXT PK | UUID |
| `name` | TEXT | Required |
| `description` | TEXT | |
| `category` | TEXT | e.g. AI/ML, DevOps, Research |
| `status` | TEXT | `active`, `complete`, `archived` |
| `completion` | INTEGER | 0100 |
| `external_url` | TEXT | Internal or external link |
| `drive_url` | TEXT | Google Drive link |
| `tags` | TEXT | JSON array of strings |
| `accent_color` | TEXT | Hex color for card theming |
| `is_new` | INTEGER | Boolean flag |
| `created_at` / `updated_at` | TEXT | ISO datetime |
**`documents`** — Files attached to projects
| Column | Type | Notes |
|---|---|---|
| `id` | TEXT PK | UUID |
| `project_id` | TEXT FK | Cascades on project delete |
| `filename` | TEXT | UUID-named file on disk |
| `original_name` | TEXT | Display name |
| `mimetype` | TEXT | |
| `created_at` | TEXT | |
**`tools`** — Available AI/dev tools catalog
| Column | Type | Notes |
|---|---|---|
| `id` | TEXT PK | UUID |
| `name` | TEXT | |
| `description` | TEXT | |
| `category` | TEXT | |
| `external_url` | TEXT | |
| `is_new` | INTEGER | Boolean — shown in dashboard spotlight |
| `added_at` | TEXT | |
| `notes` | TEXT | Usage tips, caveats |
**`settings`** — Key/value app configuration
| Key | Default | Description |
|---|---|---|
| `app_title` | `CODEDUMP` | Shown in sidebar and login page |
| `company_name` | `Your Company` | Shown under the app title |
| `logo_url` | `null` | Uploaded or external URL |
| `accent_color` | `#6366f1` | CSS variable applied globally |
---
## Auth Model
Two account types with separate login flows:
**Users** — Standard team members
- Select no username; just enter their 4-digit PIN directly on the keypad
- PINs are unique system-wide (enforced by DB unique constraint)
- Stored as `HMAC-SHA256(JWT_SECRET, pin)` — deterministic, allowing single-query lookup
- Can: create/edit/delete projects and tools, upload documents, view all content
- Cannot: access Settings or User Management
**Admins** — Elevated accounts
- Log in with username + password via the "Admin Login" link on the login page
- Passwords stored as bcrypt hashes (cost factor 10)
- Can: everything users can do, plus Settings (branding/theme) and User Management
- A bootstrap admin is created on first startup from `ADMIN_USERNAME` / `ADMIN_PASSWORD` env vars
- The last admin account cannot be deleted
**JWT** — 12-hour tokens stored in `localStorage`. Expiry is checked client-side on load; the server re-validates on every request. A 401 response from the server clears the token and redirects to `/login`.
---
## Environment Variables
| Variable | Default | Description |
|---|---|---|
| `PORT` | `3000` | Server listen port |
| `DATA_DIR` | `./data` | SQLite DB + uploads root on disk |
| `MAX_UPLOAD_MB` | `50` | Max file upload size |
| `ADMIN_USERNAME` | `admin` | Bootstrap admin username (first-run only) |
| `ADMIN_PASSWORD` | `codedump2024` | Bootstrap admin password (first-run only) — change this |
| `JWT_SECRET` | *(insecure default)* | Token signing secret — set to a 32+ char random string |
Generate a strong `JWT_SECRET`:
```bash
openssl rand -hex 32
```
---
## Running Locally
```bash
# Install all workspace dependencies
npm install
# Start both server (port 3000) and client (port 5173) with hot reload
npm run dev
```
Visit `http://localhost:5173`. The Vite dev server proxies `/api/*` to `localhost:3000`.
Default admin credentials on first run: `admin` / `codedump2024`
---
## Building for Production
```bash
npm run build
# Client builds to client/dist/
# Server builds to server/dist/
# Server serves client/dist/ as static files
npm start
```
---
## Docker
```bash
# Build image
docker build -t codedump:latest .
# Run with docker-compose (recommended)
docker-compose up -d
```
Data persists in `./data/` (local) or `/mnt/user/appdata/codedump/` (Unraid).
See [INSTALL.md](./INSTALL.md) for the full Unraid GUI setup guide including port mapping, volume paths, and all environment variable fields.
---
## File Upload Details
- Accepted types: `.md`, `.txt`, `.pdf`, `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`
- Files are stored in `DATA_DIR/uploads/` with UUID filenames
- Served publicly at `/api/uploads/:filename` via `express.static` (no auth required — needed for `<img>` tags and the markdown doc viewer)
- Upload and delete operations require authentication
- Logo uploads follow the same path; the URL is saved in settings and served the same way
---
## Deployment Notes
- SQLite with WAL mode — suitable for a single-server internal tool; no separate database service needed
- All persistent state (DB + uploads) lives under `DATA_DIR` — back up that directory
- The bootstrap admin only runs if no admin account exists in the DB; changing env vars after first run does not change existing credentials
- `JWT_SECRET` must stay consistent across restarts — changing it invalidates all active sessions