This commit is contained in:
+255
@@ -0,0 +1,255 @@
|
||||
# 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 | 0–100 |
|
||||
| `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
|
||||
Reference in New Issue
Block a user