Live project memory
Live project memory
Last updated 5/24/2026
CNBS Live Project Memory
Cannabis Business System — Persistent Cross-Session Context
Last Updated: Current session analysis
Project Version: 0.1.0 (package.json → dispensary-pos)
Repository: midwestco/cnbs
Primary Branch Strategy: main ← staging ← feature branches
1. Project Identity & Scope
CNBS (Cannabis Business System) is a multi-tenant, white-label SaaS platform for cannabis dispensary operations. It combines a point-of-sale (POS) system, e-commerce storefront, CMS, analytics suite, and compliance tooling into a single Next.js application. The product targets dispensary operators who need regulatory compliance (METRC, state-level cannabis tracking), payment processing (Square, Stripe), and customer loyalty management under one roof.
Package name (dispensary-pos) diverges from the public product name (CNBS) — this is a known identity debt item.
2. Technology Stack
| Layer | Technology | Notes |
|---|---|---|
| Framework | Next.js (App Router, v15/16 Turbopack) | next.config.ts enables Turbopack by default |
| Language | TypeScript (strict mode, ES2017 target) | tsconfig.json strict: true |
| Auth | Clerk | Organization + user sync via /api/clerk/sync/* |
| Database | Supabase (PostgreSQL + Realtime) | RLS policies assumed; Realtime WebSocket in CSP |
| ORM | Drizzle | drizzle.config.ts excluded from tsconfig |
| AI | OpenAI + Anthropic Claude | @anthropic-ai/sdk, openai in serverExternalPackages |
| Payments | Square + Stripe | Both SDKs loaded as server externals |
| Compliance | METRC API | In CSP connect-src https://*.metrc.com |
| Communications | Twilio + SendGrid + AWS SES | All three present; no consolidation |
| Styling | Tailwind + Radix UI | components.json present (shadcn/ui) |
| Testing | Jest + Cypress + Playwright | Three separate test runners active |
| CI/CD | GitHub Actions (5 workflows) | Vercel deployment target |
| Containers | Docker (production compose) | infrastructure/docker/ |
3. Current Project State
3.1 What's Built
Core POS System
- Budtender dashboard with cart sidebar, product cards, and header (
src/components/budtender/) - POS station configuration wizard (documented in
docs/POS_SETUP/action_plans/) - Cash drawer API (
/api/cash-drawer) - Payment processing route (
src/app/api/payment/process/) - Customer connect flow (POS_SETUP action plan 05 marked COMPLETE)
Analytics Suite
- 12+ analytics API routes covering customers, revenue, inventory, compliance reports, real-time data, predictions, and performance vitals
CustomerAnalyticsDashboardcomponent with dedicated test coverageCustomerSegmentationManagerwith test coverage- Real-time analytics load testing present (
__tests__/load/real-time-analytics-load.test.ts) - Analytics API reference documented at
docs/api/analytics-API-REFERENCE.md
CMS / Storefront
StorefrontConfigPanelwith test (src/__tests__/cms/StorefrontConfigPanel.test.tsx)WidgetLibrarywith test (src/__tests__/cms/WidgetLibrary.test.tsx)- CMS API integration test (
src/__tests__/integration/cms-api.test.ts) - E2E CMS workflow spec (
e2e/cms-workflows.spec.ts) - Storefront audit system planned (
docs/analysis/STOREFRONT_AUDIT_SYSTEM_PLAN.md)
Multi-Tenant / Organization Layer
- Parent-child organization architecture documented (
docs/architecture/PARENT_CHILD_ORGANIZATION_ARCHITECTURE.md) - Clerk organization sync (
/api/clerk/sync/organization,/api/clerk/sync/membership/*) - Auth role checking (
/api/auth/check-role,/api/auth/check-user-context) - Admin onboarding completion route (
/api/admin/onboarding/complete) - Product bulk operations per org (
/api/organizations/[orgId]/products/with integration test)
AI Features
- Image generation (
/api/ai/generate-image,/api/ai/generate-hero) - Color extraction from images (
/api/ai/extract-colors) - Promotion generation (
/api/ai/generate-promotion) - Save generated images to storage (
/api/ai/save-generated-image)
Compliance
- METRC package scanning (
cypress/e2e/metrc-package-scanning.cy.ts) - Cannabis purchase limits enforcement (
cypress/e2e/cannabis-purchase-limits.cy.ts) - Transfer manifests (
cypress/e2e/cannabis-transfer-manifest.cy.ts) - Waste tracking (
cypress/e2e/cannabis-waste-tracking.cy.ts) - Regulatory reporting (
cypress/e2e/regulatory-reporting.cy.ts) - Tax calculation (
cypress/e2e/cannabis-tax-calculation.cy.ts) - GDPR/CCPA compliance test (
__tests__/compliance/gdpr-ccpa-compliance.test.ts)
Canonical Data Layer
- Brands, categories, and effects endpoints (
/api/canonical/brands,/api/canonical/categories,/api/canonical/effects) - Cannabis strain database (
data-migration/cannabis-strain-database.json) - Lab testing database (
data-migration/09_lab_testing_database.json) - Vendor database (
data-migration/08_cannabis_vendor_database.json) - Pricing structures (
data-migration/07_cannabis_pricing_structures.json)
Puffutica Integration
- Inventory sync script (
scripts/sync-puffutica-inventory.js) - API test script (
scripts/test-puffutica-api.js) — currently has 2 open security issues (PR #105) - Associates API (
/api/associates,/api/associates/[associateId])
Marketing Site
redox-next-js-light/— embedded third-party Next.js template with blog and portfolio pages- Marketing landing page recently redesigned (commits
d40c3f9,bc4a591) - Careers application endpoint (
/api/careers/apply)
3.2 What's In Progress
| Item | Evidence | Status |
|---|---|---|
| Training modules pages | PR #99 open (fix(ZP-4296,97):training-modules) | Open / unmerged |
Security fixes in test-puffutica-api.js | PR #105 open | Open, awaiting review |
| Marketing page dark design alignment | Commits d40c3f9, bc4a591 in staging | Recently merged to main via PR #101 |
| Missing pages (ZP-4305, ZP-4306) | PR #98 merged | Complete |
| Sale/return/void tabs (ZP-4280) | PR #97 merged | Complete |
| Logo/branding upload (ZP-4300) | PR #97 merged | Complete |
| Invitation fix (ZP-4298) | PR #97 merged | Complete |
3.3 What's Blocked
| Item | ID | Blocker |
|---|---|---|
| Puffutica API security hardening | PR #105 | Awaiting review merge; 2 known vulnerabilities in scripts/test-puffutica-api.js |
| Training modules | PR #99 | Open since before latest staging merges; may have merge conflicts |
| DB migration to cloud | PR #103 (closed) | Security issues in scripts/migrate-to-cloud.js were fixed but the migration itself has no confirmed execution record |
| Complete DB setup script | PR #102 (closed) | 6 security issues fixed; production safety of script unclear |
| CSP enforcement in production | next.config.ts | CSP header is commented out in development; production state unknown |
4. Active Decisions & Rationale
TECH-001: Three-Runner Test Strategy (Jest + Cypress + Playwright)
Decision: Maintain all three test frameworks simultaneously.
Rationale: Jest for unit/integration, Cypress for cannabis compliance E2E flows, Playwright for visual regression. Each runner has dedicated CI workflow (.github/workflows/).
Risk: High maintenance overhead; 37 test files across three tools creates context-switching friction. No consolidation plan documented.
TECH-002: Clerk as Auth Provider with Supabase as Data Store
Decision: Clerk handles authentication and organization management; Supabase stores all business data with RLS.
Rationale: Clerk provides multi-org, role-based auth out of the box. Bidirectional sync routes (/api/clerk/sync/*) keep both systems consistent.
Risk: Sync failures between Clerk and Supabase create ghost users/orgs. The scripts/sync-clerk-data.js script and npm run db:reset exist as remediation but are manual.
TECH-003: Dual AI Provider Strategy (OpenAI + Anthropic)
Decision: Both openai and @anthropic-ai/sdk are present as server externals.
Rationale: Redundancy and capability differentiation (image generation vs. text). docs/LLM_CONTEXT.md suggests Claude is used for internal tooling/context generation.
Trade-off: Two API contracts to maintain, two cost centers, no documented fallback logic between providers.
TECH-004: Three Payment Processors (Square + Stripe + Aerosync)
Decision: Square (@square/web-sdk, square), Stripe (stripe), and Aerosync (aerosync-web-sdk) all remain in the bundle.
Rationale: Cannabis merchant accounts are frequently terminated; redundancy is a business survival requirement.
Trade-off: unsafe-inline script-src in CSP required to load Square and Stripe JS. This weakens XSS protection.
TECH-005: redox-next-js-light/ as Embedded Marketing Template
Decision: Marketing site lives as a subdirectory (redox-next-js-light/) rather than a separate repo.
Rationale: Likely acquired as a purchased template; co-located for deployment simplicity.
Risk: Template code is not TypeScript-strict, pollutes the repo's component count (100 listed), and complicates routing.
TECH-006: Prebuild Hook Validation
Decision: scripts/detect-hook-provider-mismatches.js runs as prebuild to catch React hook/provider mismatches before compilation.
Rationale: Provider nesting issues (documented in docs/PROVIDER_PATTERNS.md) were causing silent runtime failures.
Impact: Build time increased slightly; prevents a class of production bugs.
TECH-007: NODE_TLS_REJECT_UNAUTHORIZED=0 Dev Script
Decision: dev:unsafe-ssl script disables TLS validation for local development.
Risk: This is a documented escape hatch, not a default, but its presence signals certificate management friction with local Supabase or METRC sandbox environments.
5. Architectural Evolution
Phase 1 — Foundation (archived agent plans 01–08 in docs/archive/refactoring/)
Established foundation types, universal hooks, and the service layer. Agent-driven parallel workstreams defined in docs/archive/secondary-agents/. The MASTER_IMPLEMENTATION_COORDINATOR.md suggests this phase used a multi-agent development pattern with 18 specialized agents.
Phase 2 — POS Core Build
POS station setup wizard, budtender dashboard, and cart system built and documented in docs/POS_SETUP/. Action plans 01–05 show sequential delivery: database/API → UI components → station config wizard → settings management → customer connect flow.
Phase 3 — E-Commerce + CMS Layer
Storefront config panel, widget library, and CMS API routes added. docs/archive/ecommerce-agents/ documents six parallel agent tracks for this phase.
Phase 4 — Analytics & AI Enrichment
12 analytics API routes, customer segmentation, real-time dashboard, and AI-powered features (image gen, promotion gen, color extraction) added. Data enrichment via docs/archive/agent-plans/AI_DATA_ENRICHMENT.md and GLOSSARY_ENRICHMENT_ACTION_PLAN.md.
Phase 5 — Compliance Hardening (Current)
METRC integration, purchase limits, tax calculations, transfer manifests, and waste tracking E2E tests. GDPR/CCPA compliance test added. Security PRs (#102, #103) closed. PR #105 open for remaining Puffutica script vulnerabilities.
Phase 6 — Marketing & Design (Active)
Dark design system rollout across marketing pages (commits d40c3f9, bc4a591). docs/STYLE_RULES.md governs global theme. lint:style script (scripts/scan-style-violations.js) enforces it.
6. Technical Debt Inventory
| ID | Item | File/Location | Priority | Notes |
|---|---|---|---|---|
| TECH-DEBT-001 | Package name dispensary-pos vs. product name CNBS | package.json | Low | Cosmetic but confusing in logs |
| TECH-DEBT-002 | CSP header commented out | next.config.ts lines 47–52 | Critical | Production CSP state unknown; unsafe-inline in script-src active |
| TECH-DEBT-003 | Three test runners with no consolidation plan | jest.config, cypress.config.js, playwright.config.ts | High | Maintenance overhead; CI time multiplied |
| TECH-DEBT-004 | Three email providers (Twilio, SendGrid, AWS SES) with no documented routing logic | next.config.ts serverExternalPackages | High | Cost and operational complexity |
| TECH-DEBT-005 | Manual Clerk↔Supabase sync | scripts/sync-clerk-data.js | High | No automated reconciliation; data drift risk |
| TECH-DEBT-006 | redox-next-js-light/ template inflating component count | redox-next-js-light/src/ | Medium | 30+ template pages counted in repo metrics |
| TECH-DEBT-007 | data_export/*.csv and database/*.sql checked into repo | data_export/, database/ | Critical | Contains customer PII (data_export/customers.csv, data_export/users.csv); should not be in VCS |
| TECH-DEBT-008 | Unmerged PR #99 (training modules) aging | PR #99 | Medium | Open alongside active staging merges; conflict risk growing |
| TECH-DEBT-009 | NODE_TLS_REJECT_UNAUTHORIZED=0 escape hatch | package.json dev:unsafe-ssl | Medium | Certificate management friction; developer may reach for this by habit |
| TECH-DEBT-010 | Dual AI providers with no documented fallback logic | next.config.ts serverExternalPackages | Medium | Two cost centers; no circuit breaker pattern |
| TECH-DEBT-011 | scripts/setup-complete-db.js and scripts/migrate-to-cloud.js had 15 total security issues | PRs #102, #103 closed | Medium | Fixed in PRs but scripts still exist; audit whether they're used in CI |
| TECH-DEBT-012 | Vague commit messages (update, update, update) | Commits 9692a75, a017ec8, 139a1ab, e97665c, a4ba433 | Low | Hinders bisect and changelog generation |
7. Open Questions & Unresolved Trade-offs
Q1 — Is CSP enforced in production?
The next.config.ts has a cspDirectives array constructed but the Content-Security-Policy header is commented out with note "Temporarily disable CSP in development for realtime debugging." There is no environment guard ensuring it re-enables in production. This needs explicit confirmation.
Q2 — Which email provider is the canonical send path? Twilio, SendGrid, and AWS SES are all listed as server externals. No routing logic or provider hierarchy is documented anywhere in the analyzed files.
Q3 — What is the production database migration state?
database/ contains multiple SQL files (combined-migrations.sql, cloud_migration.sql, migrations-to-apply.sql). PR #103 (migrate-to-cloud security fix) was closed but the migration's execution against production is not confirmed in any tracked document.
Q4 — Is data_export/customers.csv (and related PII files) intentionally in the repository?
This is the most urgent open question. Files like data_export/customers.csv, data_export/users.csv, and data_export/payment_sessions.csv represent potential GDPR/CCPA violations if they contain real customer data and are committed to a non-private repository or accessible to all contributors.
Q5 — What is the METRC environment?
The CSP allows https://*.metrc.com but there is no documented METRC credential management or sandbox vs. production switching strategy.
Q6 — Are the Puffutica inventory syncs idempotent?
scripts/sync-puffutica-inventory.js runs via npm run sync:puffutica. No documentation on whether duplicate runs cause double inventory records.
Q7 — What is the Aerosync integration for?
aerosync-web-sdk is listed as a server external but has no corresponding API route or documentation in the analyzed files. This may be an ACH/bank transfer integration for cannabis cash-heavy transactions.
8. Key Learnings from Recent Development
L1 — Provider Nesting is a Recurring Failure Mode
docs/PROVIDER_PATTERNS.md exists and scripts/detect-hook-provider-mismatches.js runs at prebuild. This indicates the team encountered multiple instances of Context providers being consumed outside their scope. The prebuild guard is the correct fix but documentation of the specific patterns to avoid in PROVIDER_PATTERNS.md is the institutional memory.
L2 — Agent-Driven Parallel Development Leaves Documentation Debt
The docs/archive/ tree contains plans for 18+ specialized agents working in parallel. The pattern produces rapid feature delivery but creates orphaned plan documents and inconsistent naming (COMPLETE vs COMPLETED vs IMPLEMENTATION_COMPLETE suffixes). Future sessions should check docs/archive/ before assuming a feature is missing.
L3 — Security Debt Accumulates in Scripts, Not App Code
PRs #102, #103, #105 are all security fixes to scripts/ files (setup-complete-db.js, migrate-to-cloud.js, test-puffutica-api.js). The application code has security gates (auth middleware, RLS) but utility scripts are written without the same scrutiny. Automated security scanning (e.g., GitHub CodeQL) should be extended to scripts/.
L4 — Ticket References in Commits (ZP-XXXX) Imply External Issue Tracker
Commit messages reference ZP-4280, ZP-4296, ZP-4298, ZP-4300, ZP-4305, ZP-4306. The ZP- prefix suggests a Zenpilot or similar project management tool. This context is not available in the repository itself, meaning bug reproduction context lives outside VCS.
L5 — Marketing Redesign is a Distraction Tax
Four consecutive commits/PRs in recent history relate to marketing page styling (d40c3f9, bc4a591, staging merges #100, #101). While necessary for brand consistency, this volume of design churn in the main branch while compliance and training features sit in open PRs suggests a prioritization imbalance.
L6 — Style Enforcement is Automated
npm run lint:style runs scripts/scan-style-violations.js. docs/STYLE_RULES.md is the authoritative reference. The combination means style regressions are detectable before merge, which is a healthy pattern worth preserving.
9. Integration Points & Health
| Integration | Routes/Scripts | Health Signal | Notes |
|---|---|---|---|
| Clerk Auth | /api/clerk/sync/*, /api/auth/* | ⚠️ Nominal | Sync is manual; fix(ZP-4298):invitation-fix merged recently suggests auth edge cases |
| Supabase DB | All API routes | ✅ Active | Realtime in CSP connect-src; cloud migration in progress |
| METRC Compliance | cypress/e2e/metrc-package-scanning.cy.ts | ⚠️ Unknown | E2E tests exist but no API route for METRC visible in the 50 listed routes |
| Square Payments | /api/payment/process/, @square/web-sdk | ✅ Has test coverage | route.test.ts present |
| Stripe Payments | stripe server external | ⚠️ No dedicated route visible | May be in unlisted routes |
| Puffutica Inventory | scripts/sync-puffutica-inventory.js, /api/associates | 🔴 Security PR open | PR #105 unmerged |
| OpenAI | /api/ai/generate-* | ✅ Active | 5 AI routes present |
| Anthropic | @anthropic-ai/sdk | ⚠️ No dedicated route visible | May be used in server-side logic; docs/LLM_CONTEXT.md references it |
| Twilio/SendGrid/SES | Server externals only | ⚠️ No routing logic documented | Three providers, no documented hierarchy |
| Aerosync | aerosync-web-sdk server external | 🔴 Undocumented | No routes, no docs; purpose unclear |
| Backup | /api/backup | ⚠️ Unknown frequency | Single route; no scheduling documentation |
10. Team Conventions & Patterns
Naming Conventions
- API routes follow REST conventions with kebab-case paths
- Feature branches use
[author]/[descriptor]format (e.g.,taha/tickets,taha/tickets-2.0) - Security PRs auto-generated with
Security: Fix N issues in [file]title format (bot-generated from Dependabot or similar) - Ticket-linked commits use format
fix(ZP-XXXX):description-in-kebab-case
Documentation Conventions
- Agent plans archived in
docs/archive/agent-plans/with_COMPLETEsuffix appended when done - Analysis documents live in
docs/analysis/; architecture indocs/architecture/ - API references in
docs/api/; never inline in route files docs/LLM_CONTEXT.mdmaintained as a living context document for AI-assisted development sessions
Code Quality Gates
prebuild:scripts/detect-hook-provider-mismatches.js— blocks build on provider mismatcheslint:style:scripts/scan-style-violations.js— detects design system violations- Pre-commit hook via
.husky/pre-commit - GitHub Actions: 5 CI workflows including visual regression and performance monitoring
Testing Patterns
- Unit tests:
src/components/[domain]/__tests__/[Component].test.tsx - Integration tests:
__tests__/integration/orsrc/__tests__/integration/ - Security tests:
__tests__/security/orsrc/__tests__/security/ - Compliance tests:
__tests__/compliance/ - Performance tests:
__tests__/performance/ - E2E compliance:
cypress/e2e/cannabis-*.cy.ts - Visual regression: Playwright project
"Visual Regression"
Branch Strategy
mainis productionstagingaggregates feature work before merging tomain- Feature branches merge to
stagingvia PR staging→mainvia numbered PRs (currently at #105)
11. Performance Baselines & Optimization Opportunities
Known Instrumentation
__tests__/performance/customer-analytics-performance.test.ts— baseline exists__tests__/load/real-time-analytics-load.test.ts— load test for real-time analyticssrc/__tests__/performance/load-testing.ts— general load testing.github/workflows/performance-monitoring.yml— CI performance monitoring/api/analytics/vitals— Web Vitals collection endpoint active
Optimization Opportunities
OPT-001 — Package Import Optimization (Partially Done)
next.config.ts enables optimizePackageImports for @radix-ui/react-icons and lucide-react only. Candidates for addition: all @radix-ui/react-* component packages.
OPT-002 — Server External Package List Length
13 packages are marked serverExternalPackages. Large bundles like gsap, mapbox-gl, and ogl (3D graphics) should be audited for whether they're used in production paths or only in the redox-next-js-light/ template.
OPT-003 — Supabase Realtime Subscription Management
Load test at __tests__/load/real-time-analytics-load.test.ts exists, but the CSP note ("Temporarily disable CSP in development for realtime debugging") suggests Realtime WebSocket connections have caused debugging friction. Connection pooling and subscription deduplication should be verified.
OPT-004 — Analytics Route Proliferation
12 analytics API routes with overlapping concerns (/api/analytics/dashboard, /api/analytics/dashboard/performance, /api/analytics/dashboard/real-time, /api/analytics/dashboard/trends) suggest opportunity for consolidation with query parameters, reducing cold-start surface area.
OPT-005 — Three AI API Calls in Content Generation Flow
The AI routes (generate-hero, generate-image, generate-promotion, extract-colors, save-generated-image) represent a 5-step pipeline. If these are called sequentially, latency compounds. Parallelization or streaming should be evaluated.
12. Immediate Action Items (Priority Order)
| Priority | ID | Action | Owner Signal |
|---|---|---|---|
| P0 | SEC-001 | Audit data_export/*.csv and database/*.sql for PII; remove from VCS and rotate any exposed credentials | Security |
| P0 | SEC-002 | Confirm CSP header is active in production (next.config.ts line ~47) | DevOps |
| P1 | SEC-003 | Merge PR #105 (Puffutica API security fix) | Taha / Reviewer |
| P1 | DEV-001 | Resolve PR #99 (training modules) or close and re-open from fresh branch to avoid merge conflicts | Taha |
| P1 | DEV-002 | Document email provider routing logic (Twilio vs. SendGrid vs. SES) | Backend |
| P2 | ARCH-001 | Clarify Aerosync integration purpose and add to architecture docs | Backend |
| P2 | ARCH-002 | Confirm production METRC environment configuration and credential rotation schedule | Compliance |
| P2 | OPS-001 | Add idempotency documentation to scripts/sync-puffutica-inventory.js | Backend |
| P3 | DEBT-001 | Evaluate consolidating Playwright as sole E2E runner to reduce CI complexity | QA |
| P3 | DEBT-002 | Move redox-next-js-light/ to a separate repository or clearly gate it from production builds | Frontend |
This document was generated from static repository analysis. Supplement with live CI status, Supabase dashboard metrics, and ZP-ticket context for complete situational awareness.