- TypeScript 46.8%
- Svelte 16.6%
- JavaScript 15.6%
- HTML 13.7%
- PowerShell 6.9%
- Other 0.3%
| .ai-chats | ||
| .archive | ||
| .cc-iterations | ||
| .claude | ||
| .darren | ||
| .forgejo/workflows | ||
| .lookie | ||
| .perpetual-motion | ||
| .planning | ||
| .svelte-kit | ||
| .taskmaster | ||
| .vscode | ||
| ai-tech-resources | ||
| data | ||
| docs | ||
| drizzle/migrations | ||
| projects | ||
| scripts | ||
| src | ||
| templates/ci | ||
| .dockerignore | ||
| .env | ||
| .env.example | ||
| .gitignore | ||
| .gitmodules | ||
| .prettierignore | ||
| CLAUDE copy.md | ||
| CLAUDE.md | ||
| compose.prod.yaml | ||
| coolify.json | ||
| docker-compose.local.yml | ||
| docker-compose.yml | ||
| Dockerfile.backend | ||
| Dockerfile.pac-cli | ||
| drizzle.config.ts | ||
| handoff.md | ||
| healthcheck.cjs | ||
| init.sql | ||
| LICENSE | ||
| nginx.conf | ||
| pac-wrapper.js | ||
| package-lock.json | ||
| package.json | ||
| parse_sarif.py | ||
| postcss.config.js | ||
| pp-canvas-forge.code-workspace | ||
| README.md | ||
| RESUME.md | ||
| SETUP.md | ||
| SUBMODULES.md | ||
| svelte.config.js | ||
| tailwind.config.js | ||
| test.txt | ||
| tsconfig.json | ||
| vite.config.ts | ||
| worker.js | ||
🏗️ Canvas Forge
Canvas Forge is a multi-tenant Power Platform Canvas App management platform combining CLI skills, git-based version control, and a SvelteKit web application for analyzing, diagnosing, and remediating Canvas Apps at scale.
🔀 What Is Canvas Forge?
Canvas Forge is a dual-purpose repository -- both a platform and a warehouse:
🔧 Platform Code (The Application)
| Component | Location | Description |
|---|---|---|
| CLI Skills | .claude/skills/cf-*.md |
Six Claude Code skills for PAC CLI workflows |
| Git Submodule Manager | src/lib/server/services/git-*.ts |
Automated submodule lifecycle management |
| Web Application | src/ |
SvelteKit 5 SaaS (62 TypeScript, 29 Svelte files) |
| Infrastructure | docker-compose.yml, Dockerfile.* |
PostgreSQL, Redis, Ollama, PAC CLI |
| Database | src/lib/server/schema.ts |
Drizzle ORM schema |
| Scripts | scripts/ |
Utility scripts and workers |
📦 Managed Data (The Output)
| Location | What Lives Here |
|---|---|
data/users/[user]/[tenant]/[env]/[solution]/ |
Git submodules -- independent Canvas app solution repositories |
[solution]/[app]/msapp-extracted/ |
Unpacked Canvas app source (canonical working copy) |
Critical: Solutions under
data/are NOT part of the Canvas Forge application. They are independent git repos managed by it. See docs/product/INTENT.md.
📊 Project Phases
| Phase | ID Range | Status | Completion | Description |
|---|---|---|---|---|
| 🔧 Phase 1: CLI Tooling | 1-19 | Active | ~53% | PAC CLI workflows, skills, git version control |
| 🔀 Phase Git: Submodule Manager | 40-74 | Active | ~11% | Automated git lifecycle for solution repos |
| 🌐 Phase 2: Web Application | 100-115 | Planned | 0% | SvelteKit SaaS for analysis & remediation |
| 💰 Phase 3: SaaS Features | 200+ | Planned | 0% | Subscriptions, enterprise features |
Note
: Client project tasks (e.g., UTMB app features) are tracked in each solution's own
.taskmaster/, not here.
📁 Repository Structure
canvas-forge/
├── .claude/
│ └── skills/ # 🎯 Canvas Forge CLI skills (cf-*)
│ ├── cf-list-apps.md
│ ├── cf-list-tasks.md
│ ├── cf-auth.md
│ ├── cf-new.md
│ ├── cf-sync.md
│ ├── cf-analyze.md
│ ├── README.md # Skills documentation
│ └── QUICK-REF.md # Quick reference
├── .taskmaster/ # 🏗️ Platform development tasks
│ ├── tasks/
│ └── phases/
├── data/
│ └── users/
│ └── [username]/ # e.g., Darren
│ ├── .model/ # App project template
│ └── [tenant-domain]/ # e.g., doaccelerator.com
│ ├── environment.json # Tenant metadata
│ └── [environment]/ # e.g., sandbox-git
│ └── [solution]/ # 🔗 GIT SUBMODULE
│ ├── .git/ # Independent repo
│ ├── .taskmaster/ # Solution tasks
│ └── [app-name]/
│ ├── README.md
│ ├── changes/
│ ├── diff/
│ ├── docs/
│ │ └── error-analysis.md
│ ├── msapp-down/ # Downloaded .msapp files
│ ├── msapp-extracted/ # 🎯 CANONICAL SOURCE
│ ├── msapp-test/
│ └── msapp-up/
├── docs/
│ ├── product/
│ │ ├── INTENT.md # 🎯 VITAL: Project intent
│ │ └── PRD.md # Product requirements
│ ├── architecture.md # Web app architecture
│ └── reference/ # PAC CLI docs, env info
├── scripts/
│ ├── seed-dev-data.ts # Database seeding
│ └── ... # Utility scripts
├── src/ # 🌐 SvelteKit Web Application
│ ├── routes/
│ │ ├── +page.svelte # Landing page
│ │ ├── +layout.svelte # Root layout
│ │ ├── (auth)/ # 🔐 Authentication routes
│ │ │ ├── +layout.svelte
│ │ │ ├── login/
│ │ │ ├── register/
│ │ │ ├── forgot-password/
│ │ │ ├── reset-password/
│ │ │ ├── verify-email/
│ │ │ ├── verify-reminder/
│ │ │ └── logout/
│ │ ├── (app)/ # 🏢 Authenticated app routes
│ │ │ ├── +layout.svelte # App layout
│ │ │ ├── +layout.ts
│ │ │ ├── profile/ # User profile
│ │ │ ├── environments/ # Power Platform environments
│ │ │ ├── apps/ # Canvas apps browser
│ │ │ │ ├── +page.svelte
│ │ │ │ └── [appId]/
│ │ │ │ ├── +page.svelte
│ │ │ │ └── analysis/
│ │ │ └── settings/
│ │ │ └── tenants/ # Tenant management
│ │ ├── auth/
│ │ │ ├── [...all]/ # Better Auth handler
│ │ │ └── callback/
│ │ │ └── microsoft/ # OAuth callback
│ │ └── api/ # 📡 REST API endpoints
│ │ ├── auth/
│ │ │ ├── verify-email/
│ │ │ ├── verify-email-confirm/
│ │ │ ├── forgot-password/
│ │ │ ├── reset-password/
│ │ │ └── logout/
│ │ ├── user/
│ │ │ ├── update-profile/
│ │ │ ├── upload-avatar/
│ │ │ └── delete-avatar/
│ │ ├── tenants/
│ │ │ └── [id]/
│ │ │ ├── refresh/
│ │ │ └── set-default/
│ │ ├── environments/
│ │ ├── apps/
│ │ │ └── [appId]/
│ │ │ ├── analyze/
│ │ │ └── remediate/
│ │ ├── search/
│ │ └── health/
│ ├── lib/
│ │ ├── auth-client.ts # Better Auth client
│ │ ├── components/ # 🎨 Svelte UI components
│ │ │ ├── auth/
│ │ │ │ ├── AuthCard.svelte
│ │ │ │ ├── EmailInput.svelte
│ │ │ │ ├── PasswordInput.svelte
│ │ │ │ ├── AuthDivider.svelte
│ │ │ │ ├── FormError.svelte
│ │ │ │ ├── SocialAuthButton.svelte
│ │ │ │ └── VerificationBanner.svelte
│ │ │ ├── AvatarUpload.svelte
│ │ │ ├── ErrorDetailModal.svelte
│ │ │ ├── LoadingSpinner.svelte
│ │ │ ├── Modal.svelte
│ │ │ ├── PasswordStrength.svelte
│ │ │ └── Toast.svelte
│ │ ├── stores/ # 🗄️ Svelte stores
│ │ │ ├── analysis.ts
│ │ │ ├── environment.ts
│ │ │ ├── loading.ts
│ │ │ └── toast.ts
│ │ ├── types/ # 📝 TypeScript types
│ │ │ ├── git.ts
│ │ │ └── power-platform.ts
│ │ ├── utils/
│ │ │ └── validation.ts
│ │ ├── server/ # 🖥️ Server-side code
│ │ │ ├── auth.ts # Better Auth config
│ │ │ ├── db.ts # Database connection
│ │ │ ├── schema.ts # 🗄️ Drizzle ORM schema
│ │ │ ├── queue.ts # BullMQ setup
│ │ │ ├── crypto.ts
│ │ │ ├── email.ts
│ │ │ ├── rate-limiter.ts
│ │ │ ├── token-manager.ts
│ │ │ ├── token-store.ts
│ │ │ ├── power-platform-client.ts # Power Platform API
│ │ │ ├── services/ # 🔧 Business logic services
│ │ │ │ ├── app-service.ts
│ │ │ │ ├── environment-service.ts
│ │ │ │ ├── git-service.ts
│ │ │ │ ├── git-submodule-service.ts
│ │ │ │ ├── ollama-client.ts
│ │ │ │ ├── pac-cli-service.ts
│ │ │ │ ├── remediation-service.ts
│ │ │ │ ├── sarif-parser.ts
│ │ │ │ ├── storage-service.ts
│ │ │ │ └── __tests__/
│ │ │ ├── workers/ # 🏃 BullMQ background workers
│ │ │ │ └── analysis-worker.ts
│ │ │ └── email-providers/
│ │ │ └── mailgun.ts
│ │ └── index.ts
│ ├── app.d.ts # SvelteKit types
│ ├── app.html # HTML shell
│ └── hooks.server.ts # SvelteKit hooks
├── docker-compose.yml # 🐳 Dev infrastructure
├── Dockerfile.pac # PAC CLI container
├── drizzle.config.ts # Database migration config
├── package.json # Dependencies
├── svelte.config.js # SvelteKit config
├── tailwind.config.js # Tailwind CSS
├── tsconfig.json # TypeScript config
├── vite.config.ts # Vite config
├── CLAUDE.md # Claude Code instructions
├── SUBMODULES.md # Git submodules guide
└── README.md # This file
🚀 Quick Start: Web Application
Prerequisites
- Node.js 18+ and npm
- Docker and Docker Compose
- Git 2.x
- PAC CLI (Power Platform CLI) v1.51.1+
Installation
# Clone with submodules
git clone git@git.superpowerlabs.app:darren/canvas-forge.git
cd canvas-forge
git submodule update --init --recursive
# Install dependencies
npm install
# Start infrastructure (PostgreSQL, Redis, Ollama)
docker compose up -d
# Run database migrations
npm run db:migrate
# Seed development data (optional)
npm run db:seed
# Start development server
npm run dev
The web app will be available at http://localhost:5173.
Environment Variables
Create a .env file in the project root:
# Database
DATABASE_URL=postgresql://canvas:canvas@localhost:5432/canvas_forge
# Redis
REDIS_URL=redis://localhost:6379
# Better Auth
BETTER_AUTH_SECRET=your-secret-key-here
BETTER_AUTH_URL=http://localhost:5173
# Microsoft OAuth
MICROSOFT_CLIENT_ID=your-client-id
MICROSOFT_CLIENT_SECRET=your-client-secret
MICROSOFT_TENANT_ID=common
# Mailgun (optional)
MAILGUN_API_KEY=your-mailgun-key
MAILGUN_DOMAIN=your-mailgun-domain
# Ollama (optional - for AI features)
OLLAMA_URL=http://localhost:11434
🎯 Quick Start: CLI Skills
All skills use the cf- prefix and work within Claude Code:
| Skill | Purpose | Usage |
|---|---|---|
/cf-list-apps |
List all Canvas apps across tenants | Get overview of all managed apps |
/cf-list-tasks |
Aggregate all TaskMaster instances | View tasks across platform + solutions |
/cf-auth |
Set up PAC CLI authentication | First time or when auth expires |
/cf-new |
Create new app project | Start managing a new Canvas app |
/cf-sync |
Sync app with Power Platform cloud | Before/after making changes |
/cf-analyze |
Generate comprehensive analysis | After download or before changes |
Example: Starting a New App
# In Claude Code
/cf-new
This will:
- Prompt for tenant, environment, solution, and app name
- Set up folder structure from
.model/template - Initialize as git submodule (if solution)
- Configure remotes (origin + alt)
- Download app if brownfield (existing app)
- Unpack to
msapp-extracted/ - Create initial commit and push
Full Documentation: .claude/skills/README.md | Quick Reference: .claude/skills/QUICK-REF.md
🏗️ Architecture
flowchart TD
subgraph Platform["🔧 Canvas Forge Platform"]
SK[SvelteKit 5 App<br/>29 Svelte components]
API[API Routes<br/>REST + Better Auth]
GS[Git Services<br/>Submodule Manager]
PPC[Power Platform Client<br/>OAuth + Dataverse]
end
subgraph Infrastructure["⚙️ Infrastructure"]
PG[(PostgreSQL 16<br/>+ pgvector)]
RD[(Redis)]
BQ[BullMQ Workers<br/>Analysis Queue]
OL[Ollama AI<br/>Local Models]
PAC[PAC CLI Container<br/>Download/Unpack]
end
subgraph Data["📦 Managed Data"]
SM1[Solution Submodule 1<br/>Own .taskmaster/]
SM2[Solution Submodule 2<br/>Own .taskmaster/]
SMN[Solution Submodule N<br/>Own .taskmaster/]
end
SK --> API
API --> GS
API --> PPC
SK --> PG
API --> BQ
BQ --> RD
BQ --> OL
BQ --> PAC
GS -.manages.-> SM1
GS -.manages.-> SM2
GS -.manages.-> SMN
PPC -->|OAuth| Cloud[☁️ Power Platform<br/>Microsoft Dataverse]
style Platform fill:#E3F2FD
style Infrastructure fill:#FFF3E0
style Data fill:#E8F5E9
Tech Stack
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | SvelteKit 5, Tailwind CSS | Modern reactive UI |
| Backend | Node.js, TypeScript | Server-side logic |
| API | Hono (via SvelteKit routes) | REST endpoints |
| Database | PostgreSQL 16 + pgvector, Drizzle ORM | Relational data + vector search |
| Auth | Better Auth + Microsoft OAuth | Email/password + SSO |
| Queue | BullMQ + Redis | Background job processing |
| AI | Ollama (local models) | App analysis & remediation |
| Git | simple-git + child_process | Submodule lifecycle |
| Power Platform | PAC CLI, Dataverse REST API | Canvas app operations |
| Containerization | Docker Compose | Dev environment |
📊 Connected Tenants
| Tenant | User | Auth Index | Environments |
|---|---|---|---|
| utmb.edu | daneese@utmb.edu | 2 | 5 |
| superpowerlabs.co | darren@superpowerlabs.co | 1 | 6 |
| powerlabs.us | darren@powerlabs.us | 4 | 12 |
| doaccelerator.com | darren@doaccelerator.com | 3 | 8 |
🔀 Git Submodules
Solutions are independent git repositories managed as submodules. This enables:
- ✅ Independent lifecycles for each solution
- ✅ Separate TaskMaster per solution
- ✅ Clean separation between platform and solution development
- ✅ Portable solution repositories
Working with Submodules
Cloning Canvas Forge
# Clone main repo
git clone git@git.superpowerlabs.app:darren/canvas-forge.git
cd canvas-forge
# Initialize all submodules
git submodule update --init --recursive
Working in a Solution
# Navigate to solution (it's an independent repo)
cd "data/users/darren/[tenant]/[env]/[solution]"
# Make changes and commit
git add .
git commit -m "feat: add new feature"
git push origin main
git push alt main
Updating Submodule Reference
After pushing changes to a solution:
# Back in canvas-forge main repo
cd /path/to/canvas-forge
# Update submodule reference
git add "data/users/darren/[tenant]/[env]/[solution]"
git commit -m "Update [solution] submodule to latest"
git push origin main
Adding a New Solution as Submodule
# From canvas-forge root
git submodule add ssh://git@git.superpowerlabs.app:2222/darren/[solution-name].git \
"data/users/darren/[tenant]/[environment]/[Solution Name]"
git commit -m "Add [Solution Name] as git submodule"
git push origin main
Full Guide: SUBMODULES.md
📚 Key Concepts
Solution vs App
| Concept | Definition | Example |
|---|---|---|
| Solution | Power Platform Solution (can contain multiple apps) Git submodule with own .taskmaster/ |
JumpStart Kit v2026 |
| App | Individual Canvas Power App Lives inside a solution folder |
Ultimate JumpStart Kit |
Folder Purpose
| Folder | Purpose | Git Tracked |
|---|---|---|
msapp-down/ |
Downloaded .msapp files (binary ZIP archives) | ❌ No (binary) |
msapp-extracted/ |
Unpacked source (CANONICAL working copy) | ✅ YES |
msapp-test/ |
Experimental unpacked versions for testing | ❌ No |
msapp-up/ |
Packed .msapp files ready for upload | ❌ No |
msapp-temp/ |
Temporary folder for conflict resolution | ❌ No (deleted after merge) |
IMPORTANT:
msapp-extracted/is always the canonical working copy. This is what gets committed to git.
🔧 Development
Available Scripts
# Development
npm run dev # Start dev server with hot reload
npm run build # Build for production
npm run preview # Preview production build
npm run start # Start production server
# Type checking
npm run check # Type check
npm run check:watch # Type check in watch mode
# Testing
npm test # Run unit tests
npm run test:e2e # Run Playwright E2E tests
# Code quality
npm run lint # ESLint
npm run format # Prettier
# Database
npm run db:generate # Generate migration from schema
npm run db:migrate # Run migrations
npm run db:push # Push schema changes (dev only)
npm run db:studio # Open Drizzle Studio
npm run db:seed # Seed development data
Running Tests
Canvas Forge uses Vitest as the test runner for unit tests and Playwright for E2E tests.
Test Database Setup
Before running tests, ensure you have a test database available:
# Create the test database (using psql or your preferred PostgreSQL client)
createdb ppcanvasforge_test
# Or use the existing dev database URL
# Tests will use DATABASE_TEST_URL environment variable
Environment Variables
Set the DATABASE_TEST_URL environment variable to point to your test database:
# .env file
DATABASE_TEST_URL=postgresql://ppforge:ppforge_dev_password@localhost:50200/ppcanvasforge_test
Running Tests
# Run all tests
npm test
# Run tests in watch mode (for development)
npm test -- --watch
# Run tests with coverage report
npm test -- --coverage
# Run a specific test file
npm test -- src/lib/server/services/__tests__/git-submodule-db.test.ts
# Run tests matching a pattern
npm test -- --grep "CRUD Operations"
Test Structure
Tests are located in __tests__ directories within the service layer:
src/lib/server/services/
├── __tests__/
│ ├── git-service.test.ts # Git service tests
│ ├── git-submodule-db.test.ts # Git submodule DB service tests
│ └── test-db-setup.ts # Test database setup and fixtures
├── git-service.ts
├── git-submodule-db.ts
└── ...
Writing New Tests
When adding tests for new services:
- Create a
<service-name>.test.tsfile in the__tests__directory - Import test utilities from
test-db-setup.ts:setupTestDb()/closeTestDb()for connection managementcleanupTestDb()for test isolationmockSubmoduleData()for generating test datacreateTestSubmodules(count)for bulk creation
- Use
beforeAll,afterEach,afterAllhooks for setup/teardown - Group tests using
describe()blocks for each feature area
Database Schema
Key tables in src/lib/server/schema.ts:
| Table | Purpose |
|---|---|
users |
User accounts (email + OAuth) |
sessions |
Better Auth sessions |
tenants |
Power Platform tenants |
environments |
Power Platform environments |
apps |
Canvas app metadata |
app_versions |
App version history |
analyses |
App analysis results (SARIF) |
remediations |
AI-suggested fixes |
git_submodules |
Submodule tracking |
git_operations |
Git operation logs |
Adding a New API Endpoint
- Create route file:
src/routes/api/[feature]/+server.ts - Add service logic:
src/lib/server/services/[feature]-service.ts - Update types:
src/lib/types/[feature].ts - Add tests:
src/lib/server/services/__tests__/[feature]-service.test.ts
Adding a New Page
- Create route:
src/routes/(app)/[feature]/+page.svelte - Add server load:
src/routes/(app)/[feature]/+page.server.ts - Add components:
src/lib/components/[feature]/ - Update stores if needed:
src/lib/stores/[feature].ts
🔄 Power Platform CLI (PAC CLI)
Canvas Forge uses the PAC CLI for all Power Platform operations:
Essential Commands
# Authentication
pac auth list # List auth profiles
pac auth create --url https://[org].crm.dynamics.com
pac auth select --index [number]
# Canvas App Operations
pac canvas list # List apps
pac canvas download --name "[App Name]" --file-name "output.msapp"
pac canvas unpack --msapp "./file.msapp" --sources "./msapp-extracted"
pac canvas validate --sources "./msapp-extracted"
pac canvas pack --sources "./msapp-extracted" --msapp "./output.msapp"
⚠️ Deprecation Notice
pac canvas unpack and pac canvas pack are deprecated but still functional (as of PAC CLI v1.52.1). Continue using them until Microsoft announces replacements.
📖 Documentation
| Document | Purpose |
|---|---|
| docs/product/INTENT.md | VITAL -- Project intent and dual-nature definition |
| docs/product/PRD.md | Product requirements (all phases) |
| docs/architecture.md | Web application architecture |
| CLAUDE.md | Claude Code development instructions |
| SUBMODULES.md | Git submodules complete guide |
| .claude/skills/README.md | Canvas Forge skills documentation |
| .claude/skills/QUICK-REF.md | Skills quick reference |
🤝 Contributing
Code Style
- TypeScript: Strict mode enabled
- Formatting: Prettier with Svelte plugin
- Linting: ESLint 9
- Commits: Conventional Commits format
Development Workflow
- Check TaskMaster first:
.taskmaster/for platform tasks - Create feature branch:
git checkout -b feature/[name] - Make changes: Follow Canvas app naming conventions (see CLAUDE.md)
- Test:
npm testandnpm run test:e2e - Commit: Use conventional commits
- Push: To both
originandaltremotes
For Canvas App Development
- Use
/cf-syncfor all cloud synchronization - Keep
msapp-extracted/as canonical working copy - Solution tasks go in
[solution]/.taskmaster/ - Platform tasks go in root
.taskmaster/
🐛 Troubleshooting
PAC CLI Authentication
# Check auth profiles
pac auth list
# Create new profile
pac auth create --url https://[org].crm.dynamics.com
# Select profile by index
pac auth select --index [number]
Git Submodules
# Submodule not initialized
git submodule update --init --recursive
# Detached HEAD in submodule
cd data/users/[user]/[tenant]/[env]/[solution]
git checkout main
# Update all submodules
git submodule update --remote --merge
Database
# Reset database
docker compose down -v
docker compose up -d
npm run db:migrate
npm run db:seed
Docker Infrastructure
# Check services
docker compose ps
# View logs
docker compose logs -f [postgres|redis|ollama]
# Restart services
docker compose restart
# Clean rebuild
docker compose down -v
docker compose up -d --build
Common Issues
| Issue | Solution |
|---|---|
| Port already in use | Change port in vite.config.ts or kill process using port |
| Database connection failed | Check DATABASE_URL in .env and ensure Postgres is running |
| Redis connection failed | Check REDIS_URL in .env and ensure Redis is running |
| PAC CLI not found | Install PAC CLI or use Docker container |
| Submodule empty | Run git submodule update --init --recursive |
🚢 Deployment
Docker Production Build
# Build production image
docker build -t canvas-forge:latest .
# Run with docker-compose
docker compose -f docker-compose.prod.yml up -d
Environment Variables (Production)
Ensure these are set in production:
DATABASE_URL: PostgreSQL connection stringREDIS_URL: Redis connection stringBETTER_AUTH_SECRET: Strong random secretBETTER_AUTH_URL: Public URL of your appMICROSOFT_CLIENT_ID: Azure AD app client IDMICROSOFT_CLIENT_SECRET: Azure AD app client secretMAILGUN_API_KEY: Mailgun API keyMAILGUN_DOMAIN: Mailgun domain
Deployment Platforms
Canvas Forge can be deployed to:
- Coolify (primary): http://cool.superpowerlabs.cloud/
- Docker Swarm or Kubernetes
- Any Node.js hosting platform (Vercel, Netlify, etc.)
🔐 Security
- Authentication: Better Auth with Argon2 password hashing
- Sessions: Secure HTTP-only cookies
- OAuth: Microsoft Identity Platform integration
- Rate Limiting: Built-in rate limiter for API endpoints
- CSRF Protection: SvelteKit CSRF tokens
- SQL Injection: Drizzle ORM parameterized queries
📊 Monitoring
Health Check
# Check API health
curl http://localhost:5173/api/health
BullMQ Dashboard
# Add bull-board to view queue status
# (Not yet implemented - Phase 2 task)
📝 License
Private repository. All rights reserved.
🙏 Acknowledgments
- Microsoft Power Platform: PAC CLI and Canvas Apps
- SvelteKit: Web framework
- Better Auth: Authentication library
- Drizzle ORM: Database toolkit
- BullMQ: Job queue system
Git Remotes:
- Primary:
git@git.superpowerlabs.app:darren/canvas-forge.git - Pool (NAS):
ssh://git@pool:2222/darren/canvas-forge.git
Last Updated: 2026-01-29 Canvas Forge Version: 0.1.0 Skills Count: 6
For detailed development instructions, see CLAUDE.md. For git submodule workflows, see SUBMODULES.md. For project intent and architecture, see docs/product/INTENT.md.