|
| 1 | +# PaxaPOS Documentation - AI Coding Guidelines |
| 2 | + |
| 3 | +## 🎯 Project Overview |
| 4 | + |
| 5 | +This is a **SvelteKit 2.0 static documentation site** for PaxaPOS (a restaurant management system). The site is fully prerendered as static HTML and deployed via nginx. Content lives in markdown files, is auto-discovered at build time, and generates both human-readable docs and AI-optimized text files for LLM consumption. |
| 6 | + |
| 7 | +**Key Architectural Decision:** This project uses a **folder-based content discovery system** rather than manual route definitions. Adding a new markdown file automatically creates routes, navigation entries, SEO metadata, and LLM-friendly text files. |
| 8 | + |
| 9 | +## 🏗️ Architecture & Data Flow |
| 10 | + |
| 11 | +### Content Processing Pipeline |
| 12 | + |
| 13 | +1. **Source:** Markdown files in `src/routes/user-guide/Manual-Usuario/` organized by numbered folders (e.g., `10-Comenzamos/`, `20-Primeros Pasos/`) |
| 14 | +2. **Discovery:** `src/lib/utils/markdownDetector.js` scans folders via Vite's `import.meta.glob()` and auto-generates: |
| 15 | + - Slugs (filename → URL-friendly format, removing number prefixes) |
| 16 | + - Titles (extracted from first `# heading` or filename) |
| 17 | + - Categories (based on parent folder structure) |
| 18 | + - SEO metadata (auto-generated from content) |
| 19 | +3. **Build Scripts:** Two critical pre-build scripts in `scripts/`: |
| 20 | + - `generate-seo-files.mjs` → Creates `static/urls.txt`, `content-index.json`, `ai-metadata.json` |
| 21 | + - `generate-ai-files.mjs` → Generates cleaned `.txt` files in `static/llms/` for LLM consumption (strips markdown, HTML, fixes encoding issues) |
| 22 | +4. **Rendering:** `[slug]` dynamic route loads markdown, converts to HTML via `marked`, applies brand replacement via `textReplacer.ts` |
| 23 | + |
| 24 | +**Critical File:** `src/lib/utils/markdownDetector.js` - Handles all content discovery. Modify the `categorizeByFolder()` function when adding new folder categories. |
| 25 | + |
| 26 | +### Prerendering & Static Generation |
| 27 | + |
| 28 | +- **All routes are prerendered** (`export const prerender = true` in `src/routes/+layout.js`) |
| 29 | +- `svelte.config.js` explicitly lists prerender entries (required for dynamic routes) |
| 30 | +- Build output in `build/` is served by nginx (see `Dockerfile` multi-stage build) |
| 31 | +- **No server-side rendering at runtime** - everything is static HTML |
| 32 | + |
| 33 | +## 🎨 UI Patterns & Conventions |
| 34 | + |
| 35 | +### Brand Replacement System |
| 36 | + |
| 37 | +The site has a **global brand name replacement feature** allowing white-labeling: |
| 38 | + |
| 39 | +- `src/lib/helpers/textReplacer.ts` exports `replacePaxaPOS()` and reactive stores |
| 40 | +- Regex pattern `/\b(?:pax[aá][\s\-_]*pos|paxa[\s\-_]*pos|pax[aá]pos|paxapos|PaxaPos)\b/gi` matches all variations |
| 41 | +- Use `use:autoReplaceBrand` Svelte action on DOM nodes for automatic replacement (see `+layout.svelte`) |
| 42 | +- When rendering markdown: always run through `processGroupedContent()` before displaying |
| 43 | + |
| 44 | +### Theme System |
| 45 | + |
| 46 | +- **Dark mode:** Class-based (`class="dark"`) via `src/lib/stores/theme.ts` |
| 47 | +- Auto-detects system preference with `prefers-color-scheme: dark` media query |
| 48 | +- Initialized in `+layout.svelte` with `initThemeStore()` - watches for system theme changes |
| 49 | +- CSS uses Tailwind's `dark:` variant (e.g., `bg-white dark:bg-gray-900`) |
| 50 | + |
| 51 | +### Markdown Content Structure |
| 52 | + |
| 53 | +Markdown files follow a consistent pattern: |
| 54 | + |
| 55 | +```markdown |
| 56 | +# 💳 Title with Emoji |
| 57 | +<div id="anchor-id"></div> |
| 58 | + |
| 59 | +> 🎯 **Purpose callout** |
| 60 | +
|
| 61 | +## 📋 Section Heading |
| 62 | + |
| 63 | +### Step 1: Action |
| 64 | +- Details |
| 65 | +- More details |
| 66 | + |
| 67 | +--- |
| 68 | + |
| 69 | +## 💡 Tips |
| 70 | +``` |
| 71 | + |
| 72 | +**Important:** First `<div id="...">` becomes the anchor for deep linking. Headers auto-generate link icons via `addLinkIconsToHeaders()` in `[slug]/+page.svelte`. |
| 73 | + |
| 74 | +## 🔧 Development Workflows |
| 75 | + |
| 76 | +### Local Development |
| 77 | + |
| 78 | +```bash |
| 79 | +npm run dev # Runs generate scripts + starts vite dev server |
| 80 | +npm run dev:clean # Skip generation, just vite dev (faster iteration) |
| 81 | +npm run build # Full production build with all generation |
| 82 | +npm run preview # Preview build output locally |
| 83 | +``` |
| 84 | + |
| 85 | +**Build sequence matters:** SEO generation must run before AI generation (AI scripts depend on generated metadata). |
| 86 | + |
| 87 | +### Adding New Documentation |
| 88 | + |
| 89 | +1. Create markdown file in appropriate `Manual-Usuario/` subfolder (e.g., `30-Módulos Principales/38-new-feature.md`) |
| 90 | +2. Use numbered prefix for ordering within folder (38 comes after 37) |
| 91 | +3. Add first-level heading with emoji: `# 🚀 New Feature` |
| 92 | +4. No code changes needed - next build auto-discovers and generates routes |
| 93 | +5. **Verify** `svelte.config.js` doesn't need manual prerender entry (usually only for LLM API routes) |
| 94 | + |
| 95 | +### Working with Styles |
| 96 | + |
| 97 | +- **Global styles:** `src/app.css` (imported in `+layout.svelte`) |
| 98 | +- **Component styles:** Scoped `<style>` blocks in `.svelte` files |
| 99 | +- **Tailwind:** Uses Tailwind v4 via `@tailwindcss/vite` plugin - NO `postcss.config.js` needed |
| 100 | +- Special class `.markdown-content` for styled markdown output (defined in `+layout.svelte`) |
| 101 | + |
| 102 | +## 🤖 LLM/AI Integration Specifics |
| 103 | + |
| 104 | +### AI-Optimized Text Generation |
| 105 | + |
| 106 | +The `scripts/generate-ai-files.mjs` script performs aggressive cleaning: |
| 107 | + |
| 108 | +- Removes ALL HTML tags and markdown syntax (links, bold, code blocks) |
| 109 | +- Fixes UTF-8 encoding issues (`á` → `á`, etc.) - see `fixProblemCharacters()` |
| 110 | +- Normalizes whitespace (max 2 consecutive newlines) |
| 111 | +- Strips emojis from titles |
| 112 | +- Outputs plain text optimized for token efficiency |
| 113 | + |
| 114 | +**Output:** `static/llms/{slug}.txt` + `static/llms/index.txt` (full concatenated content) |
| 115 | + |
| 116 | +### ChatBot Integration |
| 117 | + |
| 118 | +- `src/lib/components/ChatBotSimple.svelte` loads markdown content dynamically |
| 119 | +- FAQ-based fallback when search fails |
| 120 | +- Uses `prepareForExport()` for brand replacement before displaying |
| 121 | +- Converts module IDs to slugs via `getSlugFromId()` for proper URL generation |
| 122 | + |
| 123 | +## 📦 Dependencies & Tools |
| 124 | + |
| 125 | +### Core Stack |
| 126 | + |
| 127 | +- **SvelteKit 2.16** with `@sveltejs/adapter-static` (static site generation) |
| 128 | +- **Svelte 5** (uses new `$state()`, `$effect()` runes - NOT Svelte 3/4 syntax) |
| 129 | +- **Vite 6.2** as build tool |
| 130 | +- **Tailwind CSS 4** via `@tailwindcss/vite` plugin |
| 131 | +- **marked 15.0** for markdown → HTML conversion (NOT mdsvex for routes) |
| 132 | + |
| 133 | +### Build Tooling |
| 134 | + |
| 135 | +- **Node 20+ required** (uses ES modules, `import.meta.glob`) |
| 136 | +- **pnpm** preferred (though npm works) |
| 137 | +- Multi-stage Docker build: Node builder → nginx production image |
| 138 | +- Nginx serves from `build/` directory on port 8080 |
| 139 | + |
| 140 | +## ⚠️ Common Pitfalls |
| 141 | + |
| 142 | +1. **Don't manually add routes** - The system auto-discovers markdown files. Adding routes in `src/routes/` bypasses content generation. |
| 143 | + |
| 144 | +2. **Slug generation rules:** |
| 145 | + - Removes number prefix (`22-Tipos-De-Pago.md` → `tipos-de-pago`) |
| 146 | + - Lowercases and strips accents |
| 147 | + - Spaces/underscores → hyphens |
| 148 | + - Study `fileNameToSlug()` in `markdownDetector.js` before renaming files |
| 149 | + |
| 150 | +3. **Prerender entries:** Dynamic routes like `[slug]` auto-generate via `entries()` function - DON'T manually list them in `svelte.config.js` unless they're API endpoints. |
| 151 | + |
| 152 | +4. **Markdown rendering order:** |
| 153 | + - Load markdown → Convert via `marked()` → Apply brand replacement → Fix image paths → Highlight search terms → Add header icons |
| 154 | + - See `$effect()` in `[slug]/+page.svelte` for full pipeline |
| 155 | + |
| 156 | +5. **Build script execution:** Always run `npm run dev` or `npm run build` (includes generation scripts). Running `vite dev` directly skips content generation. |
| 157 | + |
| 158 | +6. **Svelte 5 syntax:** This uses runes (`$state`, `$effect`, `$props`) not stores for local state. Only use stores for global state (theme, brand name). |
| 159 | + |
| 160 | +## 🔍 Key Files Reference |
| 161 | + |
| 162 | +| File | Purpose | |
| 163 | +|------|---------| |
| 164 | +| `src/lib/utils/markdownDetector.js` | Content discovery, slug generation, SEO metadata | |
| 165 | +| `scripts/generate-ai-files.mjs` | Creates LLM-optimized `.txt` files | |
| 166 | +| `scripts/generate-seo-files.mjs` | Generates sitemap, content index, metadata | |
| 167 | +| `src/routes/user-guide/[slug]/+page.js` | Loads markdown content dynamically | |
| 168 | +| `src/routes/user-guide/[slug]/+page.server.js` | Generates static routes via `entries()` | |
| 169 | +| `src/lib/helpers/textReplacer.ts` | Brand name replacement system | |
| 170 | +| `svelte.config.js` | Adapter config, prerender settings | |
| 171 | + |
| 172 | +## 🚀 Deployment Notes |
| 173 | + |
| 174 | +- Production builds to `build/` as fully static site |
| 175 | +- Nginx configuration in `nginx.conf` (health check on `/health`, SPA fallback) |
| 176 | +- Docker Compose setup in `docker-compose.yml` exposes port 3000 → 8080 |
| 177 | +- No environment variables needed (all content baked into build) |
| 178 | +- Custom domain via `CNAME` file (docs.paxapos.com) |
| 179 | + |
| 180 | +--- |
| 181 | + |
| 182 | +**When in doubt:** Check `markdownDetector.js` for content logic, `[slug]/+page.svelte` for rendering pipeline, and build scripts for generation behavior. |
0 commit comments