Initial commit: Lamassu modernization project
- Add lamassu-server, lamassu-machine, lamassu-install as submodules - Add CLAUDE.md with development guidance - Add docs/modernization-plan.md with 2026 refactoring roadmap - Add .gitignore for Node.js/Nix development Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
commit
9adee6e37f
7 changed files with 670 additions and 0 deletions
44
.gitignore
vendored
Normal file
44
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Dependencies
|
||||||
|
node_modules/
|
||||||
|
.pnpm-store/
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Nix
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
.direnv/
|
||||||
|
.devenv/
|
||||||
|
.devenv.flake.nix
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Test coverage
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# Lamassu specific
|
||||||
|
.lamassu/
|
||||||
|
*.pem
|
||||||
|
*.crt
|
||||||
|
*.key
|
||||||
9
.gitmodules
vendored
Normal file
9
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
[submodule "lamassu-server"]
|
||||||
|
path = lamassu-server
|
||||||
|
url = https://github.com/lamassu/lamassu-server.git
|
||||||
|
[submodule "lamassu-machine"]
|
||||||
|
path = lamassu-machine
|
||||||
|
url = https://github.com/lamassu/lamassu-machine.git
|
||||||
|
[submodule "lamassu-install"]
|
||||||
|
path = lamassu-install
|
||||||
|
url = https://github.com/lamassu/lamassu-install.git
|
||||||
121
CLAUDE.md
Normal file
121
CLAUDE.md
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Repository Overview
|
||||||
|
|
||||||
|
This is the Lamassu Bitcoin ATM system, consisting of three components:
|
||||||
|
|
||||||
|
- **lamassu-server/** - Backend services and admin dashboard (pnpm monorepo with Turbo)
|
||||||
|
- **lamassu-machine/** - ATM kiosk software that runs on the physical machines
|
||||||
|
- **lamassu-install/** - Production installation and upgrade scripts
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### lamassu-server (monorepo)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd lamassu-server
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Run all packages in development mode (server + admin-ui)
|
||||||
|
pnpm run dev
|
||||||
|
|
||||||
|
# Build all packages
|
||||||
|
pnpm run build
|
||||||
|
|
||||||
|
# Run tests across all packages
|
||||||
|
pnpm run test
|
||||||
|
|
||||||
|
# Run a single test file
|
||||||
|
cd packages/admin-ui && pnpm vitest run path/to/file.test.js
|
||||||
|
|
||||||
|
# Database migrations
|
||||||
|
node packages/server/bin/lamassu-migrate
|
||||||
|
|
||||||
|
# Generate SSL certificates (first-time setup)
|
||||||
|
bash packages/server/tools/cert-gen.sh
|
||||||
|
|
||||||
|
# Create admin user
|
||||||
|
node packages/server/bin/lamassu-register admin@example.com superuser
|
||||||
|
|
||||||
|
# Regenerate database types (requires running postgres)
|
||||||
|
cd packages/typesafe-db && pnpm run generate-types
|
||||||
|
```
|
||||||
|
|
||||||
|
### lamassu-machine
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd lamassu-machine
|
||||||
|
|
||||||
|
# Install and build
|
||||||
|
npm install
|
||||||
|
bash ./setup.sh
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# Development with mock hardware
|
||||||
|
node bin/fake-bills.js # In one terminal
|
||||||
|
node bin/lamassu-machine --mockBillValidator --mockBillDispenser --mockCam --mockPair '<totem>'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### lamassu-server Monorepo Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
packages/
|
||||||
|
├── server/ # Express + Apollo GraphQL backend (CommonJS)
|
||||||
|
├── admin-ui/ # React 18 + Vite + MUI admin dashboard (ESM)
|
||||||
|
├── coins/ # @lamassu/coins - cryptocurrency constants (TypeScript)
|
||||||
|
└── typesafe-db/ # @lamassu/typesafe-db - Kysely database layer (TypeScript)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dependency flow**: `server` and `admin-ui` depend on `coins` and `typesafe-db`
|
||||||
|
|
||||||
|
**Key server entry points**:
|
||||||
|
- `bin/lamassu-server` - Main HTTPS server (port 3000, client cert auth)
|
||||||
|
- `bin/lamassu-admin-server` - Admin API server
|
||||||
|
- 20+ CLI utilities in `bin/` for operations tasks
|
||||||
|
|
||||||
|
**GraphQL**: Two implementations exist:
|
||||||
|
- `lib/graphql/` - Machine-facing API
|
||||||
|
- `lib/new-admin/graphql/` - Admin dashboard API
|
||||||
|
|
||||||
|
### lamassu-machine
|
||||||
|
|
||||||
|
The ATM kiosk uses a state machine architecture (`machina.js`) in `lib/brain.js` (134KB). The UI is vanilla JavaScript with Babel transpilation.
|
||||||
|
|
||||||
|
**Hardware drivers** in `lib/`: id003, mei, puloon, ccnet (bill validators), printer, leds, camera
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
**Formatting** (enforced by husky pre-commit):
|
||||||
|
- 2-space indent, no semicolons, single quotes, trailing commas
|
||||||
|
- Prettier + ESLint with auto-fix on commit
|
||||||
|
|
||||||
|
**TypeScript**: Only in `packages/coins/` and `packages/typesafe-db/`. Use `@typescript-eslint/consistent-type-imports` for imports.
|
||||||
|
|
||||||
|
**Server code**: CommonJS (`require`/`module.exports`)
|
||||||
|
**Admin UI**: ESM (`import`/`export`)
|
||||||
|
|
||||||
|
## Database
|
||||||
|
|
||||||
|
PostgreSQL with Kysely ORM. Types are auto-generated from the schema.
|
||||||
|
|
||||||
|
**Environment**: Configure postgres connection in `packages/server/.env`
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Node.js 22+
|
||||||
|
- pnpm 10+
|
||||||
|
- PostgreSQL
|
||||||
|
- Python 3 (for native dependency builds)
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- `docs/modernization-plan.md` - 2026 modernization roadmap (Obsidian-compatible)
|
||||||
493
docs/modernization-plan.md
Normal file
493
docs/modernization-plan.md
Normal file
|
|
@ -0,0 +1,493 @@
|
||||||
|
---
|
||||||
|
title: Lamassu Modernization Plan
|
||||||
|
created: 2026-01-22
|
||||||
|
updated: 2026-01-22
|
||||||
|
tags:
|
||||||
|
- architecture
|
||||||
|
- refactoring
|
||||||
|
- roadmap
|
||||||
|
- nix
|
||||||
|
status: draft
|
||||||
|
---
|
||||||
|
|
||||||
|
# Lamassu Modernization Plan
|
||||||
|
|
||||||
|
> [!abstract] Summary
|
||||||
|
> Aggressive refactoring plan to bring Lamassu Bitcoin ATM software to 2026 standards, focusing on **reproducibility**, **security**, and **open-source maintainability** with NixOS deployment.
|
||||||
|
|
||||||
|
## Quick Links
|
||||||
|
|
||||||
|
- [[#Architecture Overview]]
|
||||||
|
- [[#Technology Decisions]]
|
||||||
|
- [[#Migration Phases]]
|
||||||
|
- [[#Trade-offs]]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TB
|
||||||
|
subgraph "NixOS Production Server"
|
||||||
|
deploy[deploy-rs / Colmena]
|
||||||
|
sops[sops-nix secrets]
|
||||||
|
|
||||||
|
subgraph "lamassu-server"
|
||||||
|
fastify[Fastify + tRPC + GraphQL]
|
||||||
|
otel[OpenTelemetry]
|
||||||
|
end
|
||||||
|
|
||||||
|
pg[(PostgreSQL + Drizzle)]
|
||||||
|
jaeger[Jaeger / Grafana]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Admin UI"
|
||||||
|
react[React 19 + TanStack]
|
||||||
|
shadcn[Shadcn/ui + Tailwind]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "lamassu-machine"
|
||||||
|
tauri[Tauri 2.x Rust Core]
|
||||||
|
xstate[XState v5]
|
||||||
|
hal[Rust HAL napi-rs]
|
||||||
|
hw[Hardware Drivers]
|
||||||
|
end
|
||||||
|
|
||||||
|
react -->|tRPC| fastify
|
||||||
|
tauri -->|GraphQL| fastify
|
||||||
|
fastify --> pg
|
||||||
|
fastify --> otel
|
||||||
|
otel --> jaeger
|
||||||
|
hal --> hw
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technology Decisions
|
||||||
|
|
||||||
|
### Runtime & Language
|
||||||
|
|
||||||
|
> [!decision] Full TypeScript + Node.js 22 LTS
|
||||||
|
> While Bun offers 3-4x performance, Node.js remains the backbone of enterprise applications. For mission-critical financial software, **reliability > raw performance**.
|
||||||
|
|
||||||
|
| Aspect | Current | Target |
|
||||||
|
|--------|---------|--------|
|
||||||
|
| Runtime | Node.js 22 | Node.js 22 LTS |
|
||||||
|
| Language | JS + partial TS | Full TypeScript (strict) |
|
||||||
|
| Modules | CommonJS + ESM mix | ESM only |
|
||||||
|
|
||||||
|
**Action Items:**
|
||||||
|
- [ ] Migrate all JavaScript to TypeScript
|
||||||
|
- [ ] Enable `strictNullChecks` and `noUncheckedIndexedAccess`
|
||||||
|
- [ ] Eliminate all CommonJS requires
|
||||||
|
|
||||||
|
#typescript #nodejs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backend Framework
|
||||||
|
|
||||||
|
> [!decision] Express → Fastify
|
||||||
|
> Fastify provides 70-80k req/s vs Express's 20-30k, with first-class TypeScript support and JSON Schema validation.
|
||||||
|
|
||||||
|
| Framework | Performance | TypeScript | Ecosystem |
|
||||||
|
|-----------|-------------|------------|-----------|
|
||||||
|
| Express | 20-30k req/s | Partial | Mature |
|
||||||
|
| **Fastify** | 70-80k req/s | First-class | Growing |
|
||||||
|
| Hono | Ultra-light | Good | Edge-focused |
|
||||||
|
|
||||||
|
**Why Fastify:**
|
||||||
|
- JSON Schema validation built-in
|
||||||
|
- HTTP/2 support
|
||||||
|
- Plugin architecture
|
||||||
|
- Better for long-running server processes
|
||||||
|
|
||||||
|
#backend #fastify
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### API Layer
|
||||||
|
|
||||||
|
> [!decision] Hybrid: tRPC + GraphQL
|
||||||
|
> tRPC for Admin UI (type-safe monorepo), GraphQL for machine communication (stable contract).
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
AdminUI -->|tRPC| Server
|
||||||
|
Machine -->|GraphQL| Server
|
||||||
|
```
|
||||||
|
|
||||||
|
**tRPC Benefits:**
|
||||||
|
- End-to-end type safety without codegen
|
||||||
|
- Faster iteration
|
||||||
|
- Smaller bundle
|
||||||
|
|
||||||
|
**Keep GraphQL for:**
|
||||||
|
- Machine API (stable contract)
|
||||||
|
- Potential non-TypeScript clients
|
||||||
|
- Consider Yoga over Apollo (lighter)
|
||||||
|
|
||||||
|
#api #trpc #graphql
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Database & ORM
|
||||||
|
|
||||||
|
> [!decision] Kysely → Drizzle ORM
|
||||||
|
> SQL-first, schema-as-code, zero binary dependencies (critical for NixOS reproducibility).
|
||||||
|
|
||||||
|
| ORM | Bundle | Cold Start | Migrations |
|
||||||
|
|-----|--------|------------|------------|
|
||||||
|
| Prisma | Heavy | Slow | Excellent |
|
||||||
|
| Kysely | Light | Fast | Basic |
|
||||||
|
| **Drizzle** | ~7kb | Fastest | Good |
|
||||||
|
|
||||||
|
**Why Drizzle:**
|
||||||
|
- SQL-like syntax (readable)
|
||||||
|
- Zero binary dependencies
|
||||||
|
- 90% reduction in cold starts
|
||||||
|
- TypeScript schema definitions
|
||||||
|
|
||||||
|
#database #drizzle #postgresql
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Frontend (Admin UI)
|
||||||
|
|
||||||
|
> [!decision] Keep React, Modernize Patterns
|
||||||
|
> React's ecosystem dominance (190M weekly downloads) makes migration unnecessary for admin dashboards.
|
||||||
|
|
||||||
|
**Modernization:**
|
||||||
|
- [ ] Upgrade to React 19 (Server Components)
|
||||||
|
- [ ] Replace MUI with Shadcn/ui + Tailwind
|
||||||
|
- [ ] TanStack Query for data fetching
|
||||||
|
- [ ] TanStack Router for type-safe routing
|
||||||
|
|
||||||
|
#frontend #react #tailwind
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Machine State Management
|
||||||
|
|
||||||
|
> [!decision] Machina.js → XState v5
|
||||||
|
> Actor-based state management with visual editor and TypeScript inference.
|
||||||
|
|
||||||
|
**Current:** `lib/brain.js` (134KB monolith)
|
||||||
|
|
||||||
|
**XState Benefits:**
|
||||||
|
- Visual state machine editor (Stately.ai)
|
||||||
|
- TypeScript 5.0+ with excellent inference
|
||||||
|
- Actor model for complex flows
|
||||||
|
- Production-tested at scale
|
||||||
|
|
||||||
|
> [!warning] Learning Curve
|
||||||
|
> XState has a steep learning curve. The mental model differs significantly from Redux/Context.
|
||||||
|
|
||||||
|
#statemachine #xstate
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Machine UI Framework
|
||||||
|
|
||||||
|
> [!decision] Vanilla JS → Tauri 2.x
|
||||||
|
> Security-first design critical for financial kiosk applications.
|
||||||
|
|
||||||
|
| Aspect | Electron | Tauri |
|
||||||
|
|--------|----------|-------|
|
||||||
|
| Bundle Size | ~100MB | **~2.5MB** |
|
||||||
|
| RAM Usage | 150-300MB | **30-50MB** |
|
||||||
|
| Startup | 1-2s | **<0.5s** |
|
||||||
|
| Security | Full Node access | **Explicit allowlist** |
|
||||||
|
|
||||||
|
**Why Tauri for ATMs:**
|
||||||
|
- Security by default (restrictive API model)
|
||||||
|
- Lower resource usage on embedded hardware
|
||||||
|
- Rust backend integrates with hardware drivers
|
||||||
|
- 35% adoption increase in 2024
|
||||||
|
|
||||||
|
#tauri #kiosk #security
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Hardware Abstraction
|
||||||
|
|
||||||
|
> [!decision] JavaScript → Rust + napi-rs
|
||||||
|
> Memory safety at compile time for hardware drivers.
|
||||||
|
|
||||||
|
```
|
||||||
|
TypeScript Application
|
||||||
|
↓
|
||||||
|
napi-rs bindings
|
||||||
|
↓
|
||||||
|
Rust HAL Layer
|
||||||
|
↓
|
||||||
|
Hardware (bill validators, printers, etc.)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- No null pointer dereferences
|
||||||
|
- No buffer overflows
|
||||||
|
- Pre-built binaries for platforms
|
||||||
|
- Integrates with Tauri (both Rust)
|
||||||
|
|
||||||
|
#rust #napi #hardware
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schema Validation
|
||||||
|
|
||||||
|
> [!decision] Yup → Zod
|
||||||
|
> Better TypeScript integration, larger ecosystem, tRPC compatibility.
|
||||||
|
|
||||||
|
| Library | Bundle | Ecosystem | tRPC |
|
||||||
|
|---------|--------|-----------|------|
|
||||||
|
| Yup | ~15kb | Mature | Manual |
|
||||||
|
| **Zod** | ~17kb | Large | Native |
|
||||||
|
| Valibot | ~1.4kb | Growing | Adapter |
|
||||||
|
|
||||||
|
**Use Valibot** for machine-side code where bundle size matters.
|
||||||
|
|
||||||
|
#validation #zod
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Observability
|
||||||
|
|
||||||
|
> [!decision] OpenTelemetry
|
||||||
|
> Vendor-neutral, unified traces/metrics/logs.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { NodeSDK } from '@opentelemetry/sdk-node'
|
||||||
|
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Self-hosted stack:**
|
||||||
|
- **Jaeger** → Distributed tracing
|
||||||
|
- **Prometheus + Grafana** → Metrics
|
||||||
|
- All deployable via NixOS modules
|
||||||
|
|
||||||
|
#observability #opentelemetry #monitoring
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
> [!decision] Passkey-First Authentication
|
||||||
|
> Resistant to phishing and credential theft.
|
||||||
|
|
||||||
|
**Current:** Client certs + Argon2 + SimpleWebAuthn
|
||||||
|
|
||||||
|
**Target:**
|
||||||
|
- Passkeys as primary auth (WebAuthn)
|
||||||
|
- Keep client certs for machine-to-server
|
||||||
|
- Upgrade to SimpleWebAuthn v10+
|
||||||
|
|
||||||
|
> [!warning] 2025 Context
|
||||||
|
> 4B credentials leaked in January 2025. Password-based auth is a liability.
|
||||||
|
|
||||||
|
#security #passkeys #webauthn
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## NixOS Infrastructure
|
||||||
|
|
||||||
|
### Development Environment
|
||||||
|
|
||||||
|
> [!decision] devenv
|
||||||
|
> 100% reproducible development environments.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# devenv.nix
|
||||||
|
{ pkgs, ... }: {
|
||||||
|
languages.javascript = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.nodejs_22;
|
||||||
|
pnpm.enable = true;
|
||||||
|
};
|
||||||
|
languages.typescript.enable = true;
|
||||||
|
languages.rust.enable = true;
|
||||||
|
|
||||||
|
services.postgres = {
|
||||||
|
enable = true;
|
||||||
|
initialDatabases = [{ name = "lamassu"; }];
|
||||||
|
};
|
||||||
|
|
||||||
|
pre-commit.hooks = {
|
||||||
|
prettier.enable = true;
|
||||||
|
eslint.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- Single `devenv.nix` replaces Docker, brew, apt
|
||||||
|
- DevContainer generation for VS Code
|
||||||
|
- Built-in PostgreSQL service
|
||||||
|
- Pre-commit hooks integration
|
||||||
|
|
||||||
|
#nix #devenv #reproducibility
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Secrets Management
|
||||||
|
|
||||||
|
> [!decision] sops-nix
|
||||||
|
> Atomic, declarative secret provisioning.
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Supports age, GPG, AWS KMS, HashiCorp Vault
|
||||||
|
- Works with existing SSH keys
|
||||||
|
- Version-control friendly (encrypted in git)
|
||||||
|
- Compatible with all NixOS deployment tools
|
||||||
|
|
||||||
|
```nix
|
||||||
|
sops.secrets.database_password = {
|
||||||
|
sopsFile = ./secrets/db.yaml;
|
||||||
|
owner = "lamassu";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#secrets #sops #security
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Production Deployment
|
||||||
|
|
||||||
|
> [!decision] deploy-rs
|
||||||
|
> Automatic rollback on failure - critical for ATM servers.
|
||||||
|
|
||||||
|
| Tool | Rollback | Secrets | Parallel |
|
||||||
|
|------|----------|---------|----------|
|
||||||
|
| **deploy-rs** | Automatic | External | Yes |
|
||||||
|
| Colmena | Manual | Built-in | Yes |
|
||||||
|
|
||||||
|
**Why deploy-rs:**
|
||||||
|
- Connects after activation to confirm availability
|
||||||
|
- Auto-rollback if machine becomes unreachable
|
||||||
|
- Critical for network config changes on remote ATMs
|
||||||
|
|
||||||
|
#deployment #deploy-rs #nixos
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Node.js Packaging
|
||||||
|
|
||||||
|
> [!tip] dream2nix
|
||||||
|
> Auto-generates Nix derivations from `package-lock.json`.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs.dream2nix.url = "github:nix-community/dream2nix";
|
||||||
|
|
||||||
|
outputs = { dream2nix, ... }:
|
||||||
|
dream2nix.lib.makeFlakeOutputs {
|
||||||
|
source = ./.;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#nix #packaging
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
### Unit/Integration
|
||||||
|
|
||||||
|
> [!check] Keep Vitest
|
||||||
|
> Already in use, works well with TypeScript.
|
||||||
|
|
||||||
|
### E2E Testing
|
||||||
|
|
||||||
|
> [!decision] Add Playwright
|
||||||
|
> TypeScript-first, auto-wait eliminates flaky tests.
|
||||||
|
|
||||||
|
**Best Practices:**
|
||||||
|
- Use accessible locators (`getByRole`, `getByLabel`)
|
||||||
|
- Test isolation (each test independent)
|
||||||
|
- Run `tsc --noEmit` in CI
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
test('user can complete transaction', async ({ page }) => {
|
||||||
|
await page.getByRole('button', { name: 'Start' }).click()
|
||||||
|
await expect(page.getByText('Insert bill')).toBeVisible()
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#testing #playwright #vitest
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration Phases
|
||||||
|
|
||||||
|
### Phase 1: Foundation
|
||||||
|
> [!todo] High Impact, Lower Risk
|
||||||
|
|
||||||
|
- [ ] Full TypeScript migration
|
||||||
|
- [ ] devenv for development environment
|
||||||
|
- [ ] Drizzle ORM migration
|
||||||
|
- [ ] OpenTelemetry instrumentation
|
||||||
|
- [ ] Nix flake for builds
|
||||||
|
|
||||||
|
### Phase 2: Backend Modernization
|
||||||
|
|
||||||
|
- [ ] Express → Fastify migration
|
||||||
|
- [ ] Add tRPC for admin API
|
||||||
|
- [ ] Zod schema validation
|
||||||
|
- [ ] Playwright E2E tests
|
||||||
|
|
||||||
|
### Phase 3: Machine Modernization
|
||||||
|
> [!warning] Higher Risk - Requires extensive testing
|
||||||
|
|
||||||
|
- [ ] XState v5 for state machine
|
||||||
|
- [ ] Tauri migration
|
||||||
|
- [ ] Rust HAL for hardware drivers
|
||||||
|
|
||||||
|
### Phase 4: Deployment
|
||||||
|
|
||||||
|
- [ ] NixOS module for lamassu-server
|
||||||
|
- [ ] sops-nix secrets management
|
||||||
|
- [ ] deploy-rs for production deployments
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Trade-offs
|
||||||
|
|
||||||
|
| Decision | We Get | We Lose |
|
||||||
|
|----------|--------|---------|
|
||||||
|
| Node.js over Bun | Stability, ecosystem | Raw performance |
|
||||||
|
| Fastify over Hono | Mature plugins | Minimal bundle |
|
||||||
|
| Drizzle over Prisma | Bundle size, speed | DX features |
|
||||||
|
| Tauri over Electron | Security, efficiency | Ecosystem maturity |
|
||||||
|
| XState over simple FSM | Visualization, debugging | Simplicity |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [Fastify vs Express 2025](https://medium.com/codetodeploy/express-or-fastify-in-2025-whats-the-right-node-js-framework-for-you-6ea247141a86)
|
||||||
|
- [tRPC vs GraphQL](https://betterstack.com/community/guides/scaling-nodejs/trpc-vs-graphql/)
|
||||||
|
- [Drizzle vs Prisma vs Kysely](https://levelup.gitconnected.com/the-2025-typescript-orm-battle-prisma-vs-drizzle-vs-kysely-007ffdfded67)
|
||||||
|
|
||||||
|
### Machine
|
||||||
|
- [Tauri vs Electron 2025](https://www.dolthub.com/blog/2025-11-13-electron-vs-tauri/)
|
||||||
|
- [XState v5](https://stately.ai/blog/2023-12-01-xstate-v5)
|
||||||
|
- [napi-rs Guide](https://blog.logrocket.com/building-nodejs-modules-rust-napi-rs/)
|
||||||
|
|
||||||
|
### NixOS
|
||||||
|
- [devenv](https://devenv.sh/)
|
||||||
|
- [sops-nix](https://github.com/Mic92/sops-nix)
|
||||||
|
- [deploy-rs](https://github.com/serokell/deploy-rs)
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- [Passkeys Guide](https://www.passkeys.com/guide)
|
||||||
|
- [OpenTelemetry Node.js](https://opentelemetry.io/docs/languages/js/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Notes
|
||||||
|
|
||||||
|
- [[CLAUDE]] - Claude Code guidance
|
||||||
|
- [[Architecture Decision Records]] - ADRs for each decision
|
||||||
|
- [[NixOS Configuration]] - Production NixOS setup
|
||||||
1
lamassu-install
Submodule
1
lamassu-install
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit c15dbbcae8902d99e056b9397bd46cbb640edce1
|
||||||
1
lamassu-machine
Submodule
1
lamassu-machine
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 8c83ad8bdbd49621a20c01d725b1ce0c8eee813e
|
||||||
1
lamassu-server
Submodule
1
lamassu-server
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 5909e609576e078e4c2189fc6cce464b8dca8a71
|
||||||
Loading…
Add table
Add a link
Reference in a new issue