Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3ec1e87
Document design system and tech stack
NathanWCarlson Nov 1, 2025
d49efb3
Merge pull request #1 from NathanWCarlson/codex/develop-plan-to-conve…
NathanWCarlson Nov 1, 2025
3e44e0c
Document onboarding wizard implementation blueprint
NathanWCarlson Nov 1, 2025
3959fe7
Merge branch 'development' into codex/develop-plan-to-convert-excel-t…
NathanWCarlson Nov 1, 2025
3260f3f
Merge pull request #2 from NathanWCarlson/codex/develop-plan-to-conve…
NathanWCarlson Nov 1, 2025
0c85ad8
Add development master plan and cross-reference docs
NathanWCarlson Nov 1, 2025
753e266
Merge branch 'development' into codex/develop-plan-to-convert-excel-t…
NathanWCarlson Nov 1, 2025
1b21fd5
Merge pull request #3 from NathanWCarlson/codex/develop-plan-to-conve…
NathanWCarlson Nov 1, 2025
70d83d1
Update README to remove design direction details
NathanWCarlson Nov 1, 2025
807e0f3
Add dynamic base-year handling blueprint
NathanWCarlson Nov 1, 2025
a39dc2b
Merge branch 'development' into codex/develop-plan-to-convert-excel-t…
NathanWCarlson Nov 1, 2025
f19b25b
Merge pull request #4 from NathanWCarlson/codex/develop-plan-to-conve…
NathanWCarlson Nov 1, 2025
f67df94
Revise README with app details and model types
NathanWCarlson Nov 1, 2025
09677e4
Add macro model screen blueprint
NathanWCarlson Nov 1, 2025
427e1fd
Merge branch 'development' into codex/develop-plan-to-convert-excel-t…
NathanWCarlson Nov 1, 2025
99131b7
Merge pull request #5 from NathanWCarlson/codex/develop-plan-to-conve…
NathanWCarlson Nov 1, 2025
41a4281
Add BTC model screen blueprint
NathanWCarlson Nov 2, 2025
e15e109
Merge branch 'development' into codex/develop-plan-to-convert-excel-t…
NathanWCarlson Nov 2, 2025
0fadf41
Merge pull request #6 from NathanWCarlson/codex/develop-plan-to-conve…
NathanWCarlson Nov 2, 2025
45aad44
Document remaining UI and validation blueprints
NathanWCarlson Nov 2, 2025
4005464
Merge branch 'development' into codex/develop-plan-to-convert-excel-t…
NathanWCarlson Nov 2, 2025
5dad646
Merge pull request #7 from NathanWCarlson/codex/develop-plan-to-conve…
NathanWCarlson Nov 2, 2025
add34ea
Remove development documentation and disclaimer
NathanWCarlson Nov 2, 2025
26a400c
Add strategy options section to README
NathanWCarlson Nov 2, 2025
88dab32
chore: bootstrap turborepo workspace
NathanWCarlson Nov 2, 2025
06b76da
Merge pull request #8 from NathanWCarlson/codex/set-up-pnpm/turborepo…
NathanWCarlson Nov 2, 2025
50231e8
feat: add nest backend with prisma and btc sync
NathanWCarlson Nov 2, 2025
d086476
Merge branch 'development' into codex/provision-postgresql-and-implem…
NathanWCarlson Nov 2, 2025
9cfd091
Merge pull request #9 from NathanWCarlson/codex/provision-postgresql-…
NathanWCarlson Nov 2, 2025
6145957
chore: scaffold ui foundation with stores and theming
NathanWCarlson Nov 2, 2025
805e105
Merge branch 'development' into codex/integrate-tailwind,-framer-moti…
NathanWCarlson Nov 2, 2025
5fc6ffc
Merge pull request #10 from NathanWCarlson/codex/integrate-tailwind,-…
NathanWCarlson Nov 2, 2025
97dba54
feat: scaffold guided modeling experience
NathanWCarlson Nov 2, 2025
e399d11
Merge branch 'development' into codex/build-onboarding-wizard-and-mod…
NathanWCarlson Nov 2, 2025
a6114c0
Merge pull request #11 from NathanWCarlson/codex/build-onboarding-wiz…
NathanWCarlson Nov 2, 2025
04ea57a
chore: add ci quality gates and telemetry scaffolding
NathanWCarlson Nov 2, 2025
76f91bf
Merge branch 'development' into codex/wire-github-actions-for-audits-…
NathanWCarlson Nov 2, 2025
741c444
Merge pull request #12 from NathanWCarlson/codex/wire-github-actions-…
NathanWCarlson Nov 2, 2025
4a642fd
refactor(models): run tests without pnpm dependency
NathanWCarlson Nov 2, 2025
f25ade1
Merge pull request #13 from NathanWCarlson/codex/create-pnpm-ingest-w…
NathanWCarlson Nov 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DATABASE_URL="postgresql://user:password@localhost:5432/bitcoin_model?schema=public"
JWT_SECRET="super-secret-jwt"
JWT_EXPIRY_SECONDS=86400
JWT_COOKIE_NAME="access_token"
COOKIE_SECRET="very-secret-cookie"
BTC_PRICE_API="https://api.coindesk.com/v1/bpi/currentprice/BTC.json"
CORS_ORIGIN="http://localhost:4200"
PORT=3000
HOST=0.0.0.0
4 changes: 4 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ['next/core-web-vitals'],
};
138 changes: 138 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
name: Quality Gates

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read
actions: read
checks: write
statuses: write

env:
PNPM_VERSION: 8.15.7

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: pnpm install --frozen-lockfile=false
- run: pnpm lint

typecheck:
name: TypeScript
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: pnpm install --frozen-lockfile=false
- run: pnpm typecheck

unit-tests:
name: Unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: pnpm install --frozen-lockfile=false
- run: pnpm test

playwright:
name: Playwright smoke tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: pnpm install --frozen-lockfile=false
- name: Install Playwright browsers
run: pnpm exec playwright install --with-deps chromium
- run: pnpm test:e2e
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report
if-no-files-found: ignore

lighthouse:
name: Lighthouse CI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: pnpm install --frozen-lockfile=false
- name: Run Lighthouse CI
run: pnpm audit:lighthouse
- uses: actions/upload-artifact@v4
if: always()
with:
name: lighthouse-report
path: reports/lighthouse
if-no-files-found: ignore

axe:
name: Axe accessibility audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: pnpm install --frozen-lockfile=false
- name: Run Axe CLI
run: pnpm audit:axe

metrics:
name: Metric thresholds
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: pnpm install --frozen-lockfile=false
- run: pnpm metrics:check
23 changes: 23 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
node_modules
.pnpm-store
.DS_Store
coverage
playwright-report
reports/lighthouse
.next
out
.env.local
.env
coverage
.DS_Store
node_modules/
dist/
.env
coverage/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
.DS_Store
.idea
.tmp
2 changes: 2 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
pnpm exec lint-staged
93 changes: 67 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
# Bitcoin24 <img src="https://github.com/bitcoin-model/bitcoin_model/blob/main/bitcoin.png" width="30" height="30">
Helping you drive Bitcoin adoption.
A web app of the opensource Bitcoin24 Model inspired by:
- <a href= "https://x.com/saylor">Michael J. Saylor</a>
- <a href="https://x.com/shirishjajodia">Shirish Jajodia</a>
- <a href="https://x.com/_ChaitanyaJ">Chaitanya Jain (CJ)</a>

## 21-year macro forecast with micro models for bitcoin strategies
<table style="background-color: orange;">
<tr>
<th>Normie</th>
<th>BTC 10%</th>
<th>BTC Maxi</th>
<th>Double Maxi</th>
<th>Triple Maxi</th>
</tr>
</table>

Bitcoin24 is designed to simulate 21-year outcomes of various Bitcoin strategies tailored for individuals, corporations, institutions, and nation-states. Users can input their own assumptions or adjust the model to explore different scenarios. Saving the file will automatically update the scenario comparison charts in the micro models' bottom section.
This web app is a 21-year macro forecast based on the Bitcoin24 open source model designed to simulate 21-year outcomes of various Bitcoin strategies tailored for individuals, corporations, institutions, and nation-states. Users can input their own assumptions or adjust the model to explore different scenarios.

Bitcoin24 does not model Bitcoin's volatility, as its volatility profile has evolved and will continue to do so in the future. This is a simplified model intended to show possible long-term outcomes of adopting a Bitcoin standard.
<table>
Expand All @@ -22,11 +16,6 @@ Bitcoin24 does not model Bitcoin's volatility, as its volatility profile has evo
</tr>
</table>

### Original Contributors
- <a href= "https://x.com/saylor">Michael J. Saylor</a>
- <a href="https://x.com/shirishjajodia">Shirish Jajodia</a>
- <a href="https://x.com/_ChaitanyaJ">Chaitanya Jain (CJ)</a>

<br>
<br>

Expand All @@ -35,26 +24,78 @@ Bitcoin24 does not model Bitcoin's volatility, as its volatility profile has evo
<br>
<br>

> [!TIP]
> 1. <a href="https://github.com/user-attachments/assets/2710d05e-cfce-41a9-84ec-eb39d0afc6e0">Bitcoin24 - Intro</a>
> 2. <a href="https://github.com/user-attachments/assets/d6842ec0-f919-4f82-8ee2-10bcc3fe8f97">Bitcoin24 - BTC</a>
> 3. <a href="https://github.com/user-attachments/assets/1379c00b-7b38-435a-8ec3-b43fd3319871">Bitcoin24 - Macro</a>
> 4. <a href="https://github.com/user-attachments/assets/3ce97819-e76e-449f-ab4a-3405dcc098f5">Bitcoin24 - Individual</a>
> 5. <a href="https://github.com/user-attachments/assets/8afa6ed9-301d-4c3d-8f90-ad1556043155">Bitcoin24 - Corporate</a>
> 6. <a href="https://github.com/user-attachments/assets/eaffca98-cb3f-4ec3-bec8-4d44b6b6fe1f">Bitcoin24 - Institution</a>
> 7. <a href="https://github.com/user-attachments/assets/6cc536b6-9087-4231-993b-b1a42477b2ae">Bitcoin24 - Nation State</a>
> 8. <a href="https://github.com/user-attachments/assets/37aab46f-a840-4aed-a48d-8179f1b48d50">Bitcoin24 - United States</a>
### Model Types
> 1. <a href="https://github.com/user-attachments/assets/d6842ec0-f919-4f82-8ee2-10bcc3fe8f97">Bitcoin24 - BTC</a>
> 2. <a href="https://github.com/user-attachments/assets/1379c00b-7b38-435a-8ec3-b43fd3319871">Bitcoin24 - Macro</a>
> 3. <a href="https://github.com/user-attachments/assets/3ce97819-e76e-449f-ab4a-3405dcc098f5">Bitcoin24 - Individual</a>
> 4. <a href="https://github.com/user-attachments/assets/8afa6ed9-301d-4c3d-8f90-ad1556043155">Bitcoin24 - Corporate</a>
> 5. <a href="https://github.com/user-attachments/assets/eaffca98-cb3f-4ec3-bec8-4d44b6b6fe1f">Bitcoin24 - Institution</a>
> 6. <a href="https://github.com/user-attachments/assets/6cc536b6-9087-4231-993b-b1a42477b2ae">Bitcoin24 - Nation State</a>
> 7. <a href="https://github.com/user-attachments/assets/37aab46f-a840-4aed-a48d-8179f1b48d50">Bitcoin24 - United States</a>
<br>

### Strategy Options
<table style="background-color: orange;">
<tr>
<th>Normie</th>
<th>BTC 10%</th>
<th>BTC Maxi</th>
<th>Double Maxi</th>
<th>Triple Maxi</th>
</tr>
</table>

<br>
<br>

# Development Documentation
- [docs/development_plan.md](docs/development_plan.md) – master roadmap for every initiative.
- [docs/design_system.md](docs/design_system.md) – design system and core tech stack (tasks 1 & 21).
- [docs/theming_motion_framework.md](docs/theming_motion_framework.md) – shared theming and motion implementation (tasks 2 & 21).
- [docs/flow_specific_ux_interactions.md](docs/flow_specific_ux_interactions.md) – onboarding, navigation, and validation behaviors (tasks 3, 10, 14, 22).
- [docs/performance_accessibility_standards.md](docs/performance_accessibility_standards.md) – performance, accessibility, and observability guardrails (task 4).
- `.github/workflows/ci.yml`, `lighthouserc.json`, and `config/metrics/slo.json` – automated quality gates, Lighthouse budgets, and telemetry thresholds backing the standards.
- [docs/shared_app_foundation.md](docs/shared_app_foundation.md) – architectural blueprint for services, data ingestion, and tooling (task 5).
- [docs/authentication_account_persistence.md](docs/authentication_account_persistence.md) – authentication and scenario persistence (tasks 6 & 11).
- [docs/scenario_persistence_controls.md](docs/scenario_persistence_controls.md) – scenario save/load UX, APIs, and revision handling (task 11).
- [docs/dynamic_base_year_handling.md](docs/dynamic_base_year_handling.md) – dynamic base-year calculations and historical pricing backbone (task 12).
- [docs/onboarding_wizard.md](docs/onboarding_wizard.md) – Get Started flow implementation (tasks 7 & 14).
- [docs/user_home_page.md](docs/user_home_page.md) – authenticated dashboard experience (task 8).
- [docs/route_guarding_navigation.md](docs/route_guarding_navigation.md) – protected routing and global navigation (task 9).
- [docs/guided_model_flow.md](docs/guided_model_flow.md) – guided BTC → Macro → model experience (task 10).




>Disclaimer: The information provided here is for general informational purposes only and should not be considered financial advice. It contains forward-looking information that is inherently unknowable. You should seek advice from a professional financial advisor and other trusted sources before acting on any of this information. The authors and publishers of this information disclaim responsibility for any action taken by users of this information. This is but one view of potential outcomes. You should inform yourself of other views, including those that might disagree.




>Additional Information: The information provided here is for general informational purposes only and should not be considered financial advice. It contains forward-looking information that is inherently unknowable. You should seek advice from a professional financial advisor and other trusted sources before acting on any of this information. The authors and publishers of this information disclaim responsibility for any action taken by users of this information. This is but one view of potential outcomes. You should inform yourself of other views, including those that might disagree.


## Backend Services
This repository now includes a NestJS/Fastify backend that exposes REST and GraphQL APIs backed by PostgreSQL via Prisma. Key features include:

- JWT authentication with httpOnly cookies for REST and GraphQL requests.
- Scenario CRUD APIs and GraphQL resolvers persisted to PostgreSQL (`scenarios` table).
- BTC price ingestion stored in the `btc_prices` table, including an automated cron sync.
- Model execution endpoint that combines scenario inputs with the latest BTC price for quick analytics.

### Getting Started
1. Copy `.env.example` to `.env` and update `DATABASE_URL`, `JWT_SECRET`, and any other environment values.
2. Install dependencies and generate the Prisma client:
```bash
npm install
npm run prisma:generate
```
3. Apply database migrations:
```bash
npm run prisma:migrate
```
4. Start the development server:
```bash
npm run start:dev
```

The REST API is served on `http://localhost:3000` and the GraphQL playground is available at `http://localhost:3000/graphql`.
17 changes: 17 additions & 0 deletions app/(auth)/home/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { HomeHero } from '@/src/components/home/HomeHero';
import { GuidedFlowBanner } from '@/src/components/home/GuidedFlowBanner';
import { LivePriceBanner } from '@/src/components/home/LivePriceBanner';
import { ModelCatalog } from '@/src/components/home/ModelCatalog';
import { ScenarioLibrary } from '@/src/components/home/ScenarioLibrary';

export default function HomePage() {
return (
<div className="space-y-10">
<HomeHero />
<GuidedFlowBanner />
<LivePriceBanner />
<ModelCatalog />
<ScenarioLibrary />
</div>
);
}
5 changes: 5 additions & 0 deletions app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { AuthenticatedShell } from '@/src/components/layout/AuthenticatedShell';

export default function AuthLayout({ children }: { children: React.ReactNode }) {
return <AuthenticatedShell>{children}</AuthenticatedShell>;
}
30 changes: 30 additions & 0 deletions app/(auth)/models/btc/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client";

import { useRouter } from 'next/navigation';
import { FlowShell } from '@/src/components/flow/FlowShell';
import { BTCInputsPanel } from '@/src/components/models/BTCInputsPanel';
import { BTCResults } from '@/src/components/models/BTCResults';
import { useGuidedFlowStore } from '@/src/state/guidedFlowStore';

export default function BTCModelPage() {
const markStep = useGuidedFlowStore((state) => state.markStep);
const router = useRouter();

return (
<FlowShell
step="btc"
onBack={() => {
markStep('btc', { status: 'draft' });
router.push('/home');
}}
onNext={() => {
markStep('btc', { status: 'complete' });
router.push('/models/macro');
}}
nextLabel="Next: Macro"
>
<BTCInputsPanel />
<BTCResults />
</FlowShell>
);
}
29 changes: 29 additions & 0 deletions app/(auth)/models/corporate/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use client";

import { useRouter } from 'next/navigation';
import { FlowShell } from '@/src/components/flow/FlowShell';
import { ModelDetail } from '@/src/components/models/ModelDetail';
import { useGuidedFlowStore } from '@/src/state/guidedFlowStore';

export default function CorporateModelPage() {
const markStep = useGuidedFlowStore((state) => state.markStep);
const router = useRouter();

return (
<FlowShell
step="model"
onBack={() => {
markStep('model', { status: 'draft' });
router.push('/models/macro');
}}
onNext={() => {
markStep('model', { status: 'complete' });
router.push('/home');
}}
backLabel="Back: Macro"
nextLabel="Finish & Save"
>
<ModelDetail model="corporate" />
</FlowShell>
);
}
Loading