Getting started with Cannabis
Install the source, configure PostgreSQL, sessions, and S3 storage, apply migrations, create the first user, and run dispensary onboarding.
Live demo
A hosted demo runs at cannabis.openship.org. It is a shared evaluation instance; do not enter real customer, license, or payment information.
Requirements
- Node.js 20 or later (
engines.nodeis>=20.0.0; the README recommends Node 22 for Next.js 16). - A PostgreSQL database you are allowed to migrate.
- S3-compatible object storage. In production the storage variables are required at configuration load time.
- npm (the repository ships a
package-lock.json).
Install
git clone https://github.com/openshiporg/openfront-cannabis.git
cd openfront-cannabis
npm ciEnvironment
features/keystone/config/environment.ts reads the runtime configuration:
DATABASE_URL=postgresql://user:password@127.0.0.1:5432/openfront_cannabis
SESSION_SECRET=replace-with-at-least-32-random-characters
S3_BUCKET_NAME=your-bucket
S3_REGION=your-region
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
S3_ENDPOINT=https://your-s3-compatible-endpointDATABASE_URLandSESSION_SECRETare always required.SESSION_SECRETmust be at least 32 characters; generate one withopenssl rand -hex 32.- The five
S3_*variables are required whenNODE_ENV=production. Outside production the code falls back to placeholder values, so uploads only work once you set real ones. - Optional:
SMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASSWORD,SMTP_FROM, andSMTP_STORE_LINKfor password-reset email;OPENROUTER_API_KEY,OPENROUTER_MODEL, andOPENROUTER_MAX_TOKENSfor the dashboard AI chat. See Integrations and boundaries.
Never commit .env.
Migrations
The repository has eleven migration directories: seven inherited starter migrations and four Cannabis migrations (bounded core, premises storefront settings, store logo, currency and command recovery).
npx keystone build --no-ui
npm run migratenpm run migrate runs prisma migrate deploy. npm run migrate:gen builds the schema, regenerates the dashboard view order, and runs prisma migrate dev; use it only against a disposable development database.
Neither npm run dev nor npm run build applies migrations. Run npm run migrate yourself before starting the app.
Run locally
npm run dev- Public menu:
/ - Operator dashboard:
/dashboard - GraphQL API:
/api/graphql
Other scripts: npm run typecheck, npm run lint, and npm test (Node's test runner over tests/*.test.ts).
First user and onboarding
- On an empty database, open
/dashboard/initto create the first administrator, then sign in. - The dashboard shell shows a setup launcher that opens the onboarding dialog. Choose a blank pack or the sample store.
- Fill in the authority pack: organization and legal name, jurisdiction code, premises name, code, address, IANA timezone and ISO currency, license number, type, regulator and validity, owner credential, sales rules (minimum ages, operating hours, purchase limits, tax and discount rules, allowed tender types, label, return, outage, privacy and retention rules), tender configurations, and a traceability provider code.
- Submit.
runCannabisOnboardingrequires thecanManageOnboardingpermission and creates theOrganization,Premises,CannabisLicense, an OwnerRole, the owner'sStaffCredential, aJurisdictionRulePack,TenderConfigurationrecords, an unconfigured traceabilityIntegrationInstallation, andStorefrontSettings.
The dialog can also load a sample store from features/platform/onboarding/lib/seed.json. Its license, credential, lab, and manifest details are fictional and must be replaced before any real use. dismissCannabisOnboarding hides the setup prompt without installing anything.
After onboarding, review licenses, staff, rules, registers, products, and package inventory before selling.
Deployment
The repository includes railway.toml:
- Build:
keystone build --no-ui && next build(same asnpm run build). - Start:
npm run migrate && next start, so migrations run at start, when the database is reachable.
The README also has a Vercel deploy button that prompts for DATABASE_URL, SESSION_SECRET, and the four S3 credentials; add S3_ENDPOINT as well. On any host:
- Provision PostgreSQL and S3-compatible storage, and back up the database before upgrades.
- Set
NODE_ENV=production,DATABASE_URL,SESSION_SECRET, and all fiveS3_*variables through the host's secret store. - Run
npm run migrateas a deploy or start step, thennpm start. - Create the first user at
/dashboard/initand complete onboarding with your own license and rule data.
Openfront Cannabis
Self-hosted dispensary menu and operator application for licenses, staff authority, package custody, recalls, in-store POS, cash, and reconciliation.
Cannabis architecture and workflows
Keystone schema by domain, operator workflows and status transitions, GraphQL commands and queries, and access control.