diff --git a/ai-tools-dashboard/.dockerignore b/ai-tools-dashboard/.dockerignore new file mode 100644 index 0000000..f80b7cc --- /dev/null +++ b/ai-tools-dashboard/.dockerignore @@ -0,0 +1,6 @@ +node_modules +*/node_modules +*/dist +data +.git +*.log diff --git a/ai-tools-dashboard/Dockerfile b/ai-tools-dashboard/Dockerfile new file mode 100644 index 0000000..bb37eaf --- /dev/null +++ b/ai-tools-dashboard/Dockerfile @@ -0,0 +1,53 @@ +# ── Stage 1: Build client ─────────────────────────────────────────────────── +FROM node:20-alpine AS client-builder +WORKDIR /build + +COPY package.json ./ +COPY client/package.json ./client/ +COPY server/package.json ./server/ + +RUN npm install --workspace=client + +COPY client/ ./client/ +RUN npm run build --workspace=client + +# ── Stage 2: Build server ─────────────────────────────────────────────────── +FROM node:20-alpine AS server-builder +WORKDIR /build + +COPY package.json ./ +COPY server/package.json ./server/ + +RUN npm install --workspace=server + +COPY server/ ./server/ +RUN npm run build --workspace=server + +# ── Stage 3: Runtime ──────────────────────────────────────────────────────── +FROM node:20-alpine AS runtime +WORKDIR /app + +ENV NODE_ENV=production +ENV PORT=3000 +ENV DATA_DIR=/data +ENV MAX_UPLOAD_MB=50 +ENV ADMIN_USERNAME=admin +ENV ADMIN_PASSWORD=codedump2024 +ENV JWT_SECRET=changeme-use-a-long-random-string + +# Install production deps only +COPY package.json ./ +COPY server/package.json ./server/ +RUN npm install --workspace=server --omit=dev + +# Copy built artifacts +COPY --from=server-builder /build/server/dist ./server/dist +COPY --from=client-builder /build/client/dist ./client/dist + +VOLUME ["/data"] +EXPOSE 3000 + +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \ + CMD wget -qO- http://localhost:3000/api/settings || exit 1 + +CMD ["node", "server/dist/index.js"] diff --git a/ai-tools-dashboard/INSTALL.md b/ai-tools-dashboard/INSTALL.md new file mode 100644 index 0000000..8a3ded7 --- /dev/null +++ b/ai-tools-dashboard/INSTALL.md @@ -0,0 +1,185 @@ +# Unraid Install Guide — CODEDUMP + +## Prerequisites + +- Unraid 6.10 or later +- Docker enabled (default on all modern Unraid installs) +- Community Applications plugin installed (recommended, not required) + +--- + +## Option A — Community Applications (Easiest) + +> Use this if you have the CA plugin installed. + +1. Open the **Apps** tab in the Unraid web UI. +2. Search for **CODEDUMP**. +3. Click **Install** and fill in the variables described in the [Variables](#variables) section below. +4. Click **Apply**. + +--- + +## Option B — Manual Docker Container (No CA Plugin) + +### Step 1 — Open the Docker tab + +In the Unraid web UI, click **Docker** in the top navigation bar. + +### Step 2 — Add a new container + +Click **Add Container** at the bottom of the page. + +### Step 3 — Fill in Basic Settings + +| Field | Value | +|---|---| +| **Name** | `codedump` | +| **Repository** | `your-registry/codedump:latest` *(or build locally — see below)* | +| **Network Type** | `bridge` | +| **Console shell command** | `sh` | + +> **Building locally:** If you cloned this repo to Unraid, open a terminal and run: +> ```bash +> cd /path/to/ai-tools-dashboard +> docker build -t codedump:local . +> ``` +> Then set **Repository** to `codedump:local`. + +### Step 4 — Port Mapping + +Click **Add another Path, Port, Variable, Label or Device** → **Port**. + +| Field | Value | +|---|---| +| **Name** | `WebUI` | +| **Container Port** | `3000` | +| **Host Port** | `3000` *(or any open port on your Unraid server)* | +| **Connection Type** | `TCP` | + +### Step 5 — Volume (Persistent Data) + +Click **Add another Path, Port, Variable, Label or Device** → **Path**. + +| Field | Value | +|---|---| +| **Name** | `Data` | +| **Container Path** | `/data` | +| **Host Path** | `/mnt/user/appdata/codedump` | +| **Access Mode** | `Read/Write` | + +> This single volume stores the **SQLite database**, all **uploaded files**, and **user accounts**. +> Unraid creates the directory automatically on first run. + +### Step 6 — Environment Variables {#variables} + +For each variable, click **Add another Path, Port, Variable, Label or Device** → **Variable**. + +| Variable | Default | Required | Description | +|---|---|---|---| +| `PORT` | `3000` | No | Port the app listens on inside the container. Match to your Container Port above. | +| `DATA_DIR` | `/data` | No | Path inside the container for persistent data. Do not change unless you remapped the volume. | +| `MAX_UPLOAD_MB` | `50` | No | Maximum upload size in MB for documents and logos. | +| `ADMIN_USERNAME` | `admin` | **Yes** | Username for the bootstrap admin account. Set this before first launch. | +| `ADMIN_PASSWORD` | `codedump2024` | **Yes** | Password for the bootstrap admin account. **Change this to something strong.** | +| `JWT_SECRET` | *(insecure default)* | **Yes** | Secret used to sign login tokens. Set to a long random string (32+ chars). | + +> **Security note:** `ADMIN_PASSWORD` and `JWT_SECRET` must be changed from their defaults before exposing CODEDUMP to your network. The bootstrap admin is only created once — changing `ADMIN_PASSWORD` after first launch has no effect on the existing account (use the Admin → Users page instead). + +### Step 7 — WebUI Link (Optional but Recommended) + +| Field | Value | +|---|---| +| **WebUI** | `http://[IP]:[PORT:3000]` | + +This adds a clickable **WebUI** button on the Docker tab. + +### Step 8 — Apply + +Click **Apply**. Unraid will pull/build the image and start the container. + +--- + +## First Launch & Login + +1. Open `http://YOUR-UNRAID-IP:3000` in your browser. +2. You will be redirected to the **login page**. +3. Click **Admin Login** at the bottom of the login screen. +4. Enter the `ADMIN_USERNAME` and `ADMIN_PASSWORD` you set in the environment variables. +5. Once in, navigate to **Admin → Users** to create user accounts for your team. + +### User Account Types + +| Type | Login Method | Access | +|---|---|---| +| **Admin** | Username + Password | Full access including Settings and User Management | +| **User** | Select name → 4-digit PIN | Projects, Tools, Documents — all read/write | + +### Creating Users (Admin only) + +1. Click **Users** in the sidebar (Admin section). +2. Click **New User**. +3. Enter a username, select role **User**, and assign a **4-digit PIN**. +4. The user's name will appear on the login screen — they select it and enter their PIN. + +--- + +## Updating + +### Registry image: +1. Go to **Docker** tab → click the container icon → **Update** (or Force Update). +2. The `/data` volume is preserved — database, uploads, and user accounts are safe. + +### Locally built image: +```bash +cd /path/to/ai-tools-dashboard +git pull +docker build -t codedump:local . +``` +Then restart the container from the Unraid Docker tab. + +--- + +## Backup + +Everything lives in one directory: + +``` +/mnt/user/appdata/codedump/ +├── dashboard.db ← SQLite database (projects, tools, settings, users) +└── uploads/ ← Uploaded files (logos, markdown docs) +``` + +Back this up with Unraid's **Appdata Backup** plugin or any solution that covers `/mnt/user/appdata`. + +--- + +## Generating a Strong JWT_SECRET + +Run this in an Unraid terminal or any Linux shell: + +```bash +openssl rand -hex 32 +``` + +Paste the output as the value of `JWT_SECRET`. + +--- + +## Port Conflicts + +Change **Host Port** to an unused port (e.g. `3100`) and update the WebUI link to match. + +--- + +## Troubleshooting + +| Symptom | Fix | +|---|---| +| Stuck on login / "Session expired" | Clear browser localStorage and reload. | +| "No user accounts yet" on login | Log in as admin first, then create users via Admin → Users. | +| Admin can't log in after reinstall | If `/data` was wiped, bootstrap re-runs on next start using the current env vars. | +| Container exits immediately | Check Docker logs — usually a permissions issue on `/data`. | +| Can't upload files | Verify `MAX_UPLOAD_MB` and that the host path is writable. | +| Blank page / 404 | Wait 15 seconds after start, then refresh. | + +View container logs: **Docker tab** → click the container icon → **Logs**. diff --git a/ai-tools-dashboard/client/index.html b/ai-tools-dashboard/client/index.html new file mode 100644 index 0000000..63ceef9 --- /dev/null +++ b/ai-tools-dashboard/client/index.html @@ -0,0 +1,15 @@ + + +
+ + +{project.category}
+{project.description}
+ )} + + {/* Progress */} +{tool.description}
+ )} + + {tool.notes && ( +{tool.notes}
+ )} + +
+ {user.role === 'user' ?
{users.length} account{users.length !== 1 ? 's' : ''}
++ Users log in with a 4-digit PIN from the main login screen and can update projects, upload docs, and manage tools.{' '} + Admins log in with username & password and also have access to Settings and User Management. +
+No user accounts yet.
+ ++ Permanently delete {deleteTarget.username}? +
+This cannot be undone.
+ {deleteError && ( +{deleteError}
+ )} +{label}
+{value}
+ {sub &&{sub}
} +High-level overview of tools and projects.
+Overall Portfolio Progress
+ {avgCompletion}% +No projects yet.
+ + Create your first project → + +{settings.company_name}
+Enter your PIN
+4-digit PIN to sign in
+{error}
} +CODEDUMP · Internal Tool
+ + +{project.description}
} +Completion
+Links
+ {project.external_url && ( + +Tags
+Documents
+ + +No documents yet.
+ ) : ( +{docContent}
+ )}
+ Select a document to preview it here
+ +This will permanently delete {project.name} and all its documents. This cannot be undone.
+{projects.length} project{projects.length !== 1 ? 's' : ''}
++ {projects.length === 0 ? 'No projects yet. Create your first one.' : 'No projects match your filters.'} +
+Customize your dashboard branding and appearance.
+ + +{tools.length} tool{tools.length !== 1 ? 's' : ''}{newCount > 0 && ` · ${newCount} new`}
+{tools.length === 0 ? 'No tools yet. Add your first one.' : 'No tools match your filters.'}
+