This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Auto Drive is a decentralized content-addressed storage platform built on the Autonomys Network. It stores files as IPLD (InterPlanetary Linked Data) nodes on the Autonomys Distributed Storage Network (DSN). The system provides a web UI, REST API, S3-compatible API, and GraphQL API.
Yarn 4.2.2 monorepo with workspaces in apps/, packages/, and submodules/.
- apps/backend — Express.js API server (ESM, TypeScript). Runs as multiple processes: frontend API, download API, frontend worker, download worker, publish worker (dedicated on-chain publisher).
- apps/frontend — Next.js 14 web app (React 18, Tailwind CSS, Zustand, Apollo Client). Routes are under
src/app/[chain]/. - apps/auth — Express.js auth microservice (JWT, OAuth via Google/Discord/GitHub, SIWE for Web3). Deployable as AWS Lambda.
- apps/hasura — Hasura GraphQL engine config (migrations and metadata).
- apps/landing — Next.js landing page.
- packages/models — Shared TypeScript types and schemas (
@auto-drive/models). - packages/s3 — S3-compatible DTOs (
@auto-drive/s3). - packages/ui — Shared React components (
@auto-drive/ui). - packages/contracts — Solidity smart contracts (Foundry/OpenZeppelin) for payment system.
- submodules/files-gateway — IPLD node indexer and file retriever.
# Install dependencies
yarn install
# Initialize git submodules (required first time, and in each new worktree)
make init-submodules
# ⚠️ Worktrees do NOT inherit initialized submodules from the main repo.
# If `yarn install` fails with "Workspace not found (@auto-files/rpc-apis)",
# run `git submodule update --init --recursive` or `make init-submodules`.
# Build everything (submodules + models + ui + s3 + frontend + backend)
make all
# Build shared packages only (install + submodules + models + s3 + ui)
make common
# Build individual packages
yarn models build
yarn s3 build
yarn ui build
yarn backend build
yarn auth build
yarn landing build
# Build smart contracts (requires Foundry)
cd packages/contracts && forge build
# Update Autonomys SDK dependencies across all packages
yarn update:autonomys# Start infrastructure (PostgreSQL, RabbitMQ, Hasura)
docker compose -f docker-compose.dev.yml --env-file .env.dev up -d
# Run database migrations
yarn backend db-migrate up
yarn auth db-migrate up
cd apps/hasura && hasura migrate apply --admin-secret myadminsecretkey && hasura metadata apply --admin-secret myadminsecretkey && cd -
# Start services (each in separate terminal)
yarn frontend dev # Next.js on port 8080
yarn backend start:fe # Backend frontend server on port 3000
yarn auth start # Auth on port 3030
yarn landing dev # Landing page dev serverBackend can also be started as split processes:
yarn backend start:fe:api— Frontend API onlyyarn backend start:fe:worker— Upload processing worker only (fast frontend tasks)yarn backend start:publish:worker— On-chain publishing worker only (dedicatedpublish-managerconsumer; must run as a single process)yarn backend start:download:api— Download API onlyyarn backend start:download:worker— Download worker only
# Run all tests (backend + auth)
yarn test
# Run backend tests only
yarn backend test
# Run auth tests only
yarn auth testTests use Jest with --experimental-vm-modules for ESM support and --runInBand (sequential execution). Backend tests use TestContainers for PostgreSQL and RabbitMQ (Docker required). Tests are organized as:
apps/backend/__tests__/e2e/— End-to-end tests (uploads, downloads, objects, users)apps/backend/__tests__/integration/— Integration tests (S3 SDK)apps/backend/__tests__/unit/— Unit tests (core logic, repositories, event router)apps/auth/__tests__/— Auth service tests
Smart contract tests use Foundry: cd packages/contracts && forge test
# Lint all services
yarn lint
# Lint individual services
yarn backend lint
yarn auth lint
yarn frontend lint
yarn landing lintESLint with @typescript-eslint, Prettier integration. Backend/auth also use eslint-plugin-require-extensions to enforce .js import extensions.
yarn frontend codegenThe backend follows a clean layered architecture:
app/— HTTP layer.controllers/handle Express routes,apis/compose Express apps,servers/are entry points that start APIs + workers.core/— Business logic (use cases). Pure functions that orchestrate repositories and services. Functions returnneverthrowResulttypes for typed error handling.infrastructure/— External integrations:drivers/— Database (pg), message queue (RabbitMQ/amqplib), Substrate chain connection, logging, metrics.repositories/— PostgreSQL data access (objects metadata/nodes/ownership, uploads, users/accounts, S3 mappings).services/— Auth verification, download caching (multi-tier: memory → filesystem → DSN), file gateway (DSN retrieval), on-chain publisher (Substrate), payment manager (EVM/viem), upload processor.eventRouter/— RabbitMQ task processing. Tasks include:migrate-upload-nodes,publish-nodes,tag-upload,archive-objects,async-download-created,populate-cache.
errors/— Typed HTTP errors extendingHttpErrorbase class withhandleResponse().shared/utils/— Express helpers (asyncSafeHandlerwraps route handlers), filesystem utils, misc utilities.
Backend uses neverthrow for typed errors in core logic. Functions return Result<T, E> instead of throwing. HTTP errors extend HttpError with status codes and are handled via handleError() in controllers.
- Next.js App Router with dynamic
[chain]segment (supports mainnet/taurus). - State management with Zustand stores.
- GraphQL via Apollo Client (Hasura) + REST calls to backend.
- Web3 integration via wagmi/viem/RainbowKit.
- Auth via next-auth with custom JWT handling for the auth service.
- Upload: Client → Backend API → chunks to IPLD nodes → stores in PostgreSQL → publishes to RabbitMQ → Worker publishes nodes on-chain via Substrate RPC.
- Download: Client → Download API → checks memory cache → filesystem cache → retrieves from DSN via files-gateway → streams back.
- Auth: Client → next-auth → Auth service (JWT) → Backend validates JWT on each request.
PostgreSQL with db-migrate for migrations. Migration SQL files live in apps/backend/migrations/sqls/ and apps/auth/migrations/sqls/. Key tables: metadata, nodes, object_ownership, subscriptions, interactions, intents, uploads.*.
RabbitMQ queues: task-manager, download-manager, publish-manager, frontend-errors, download-errors, publish-errors. On-chain publishing (publish-nodes, ensure-object-published) is isolated on publish-manager, consumed only by the single publish worker. Tasks have a retry mechanism with retriesLeft counter; a failed task retries on its own queue and lands on the matching *-errors queue when retries are exhausted.
- ESM modules — Backend and auth use
"type": "module". All imports must use.jsextensions (even for.tsfiles). Enforced byeslint-plugin-require-extensions. - Strict TypeScript — All packages use
strict: true. Backend/auth usemodule: "ESNext"withmoduleResolution: "node". - Prettier — Single quotes,
jsxSingleQuote: true, tab width 2, trailing commas ("all"), print width 80. Backend/auth/ui:semi: false(no semicolons). Frontend/landing:semi: true(with semicolons) and useprettier-plugin-tailwindcss. - Workspace references — Internal packages use
"workspace:*"in package.json. - Logging — Use
createLogger('namespace')frominfrastructure/drivers/logger.ts. - Config — Centralized in
apps/backend/src/config.ts, reads from environment variables with defaults. - Environment setup — Each app has a
.env.samplefile. Copy to.envand customize before running.