Arco - Project Context for Claude
December 30, 2025 · View on GitHub
Overview
Arco is a desktop backup management application built with Go backend and Vue frontend using Wails3 framework. It uses SQLite for local data storage and integrates with Borg backup.
Tech Stack
- Language: Go 1.25, TypeScript/Vue 3
- Framework: Wails3 (desktop app framework)
- Database: SQLite (local file-based)
- ORM: Ent (type-safe entity framework)
- Migrations: Atlas with Goose
- Frontend: Vue 3 with TypeScript, Vite, Tailwind CSS, DaisyUI
- Task Runner: Task (https://taskfile.dev)
- Backup: Borg backup integration
Project Structure
/
├── backend/
│ ├── app/ # Application services
│ │ ├── auth/ # Authentication service + JWT interceptor
│ │ ├── backup/ # Backup management service
│ │ ├── keyring/ # Secure credential storage (system keyring)
│ │ ├── plan/ # Plan service
│ │ ├── subscription/ # Subscription service
│ │ └── user/ # User management service
│ ├── cmd/ # Command line entry points
│ │ └── root.go # Main application entrypoint
│ ├── ent/ # Database models and ORM
│ │ ├── schema/ # Entity definitions
│ │ └── migrate/ # Database migrations
│ └── api/ # Generated API code
│ └── v1/ # Proto-generated Go code
├── frontend/
│ ├── bindings/ # Generated Go-TypeScript bindings
│ ├── src/
│ │ ├── components/ # Vue components
│ │ ├── views/ # Vue views/pages
│ │ ├── stores/ # Pinia stores
│ │ ├── utils/ # Frontend utilities
│ │ └── assets/ # Static assets
│ ├── index.html # Entry HTML
│ └── vite.config.ts # Vite configuration
├── proto/ # Protocol Buffer definitions (shared with cloud)
│ ├── Taskfile.proto.yml # Proto-specific tasks
│ ├── buf.yaml # Buf configuration
│ └── api/v1/ # Proto source files
│ ├── auth.proto # Authentication service
│ ├── user.proto # User management service
│ ├── plan.proto # Plan service
│ └── subscription.proto # Subscription service
├── build/ # Build assets and icons
├── db/ # Database related files
│ └── migrations/ # Goose migrations
├── .github/ # GitHub Actions workflows
├── sync-proto.fish # 2-way proto sync with cloud repo
└── Taskfile*.yml # Task automation files
Key Commands
Development
NO_COLOR=1 task dev- Run application in development mode with hot reloadNO_COLOR=1 task build- Build the application for current platformNO_COLOR=1 task package- Package application for distributionNO_COLOR=1 task run- Run the built applicationtask test- Run teststask dev:format- Format Go codetask dev:lint- Lint Go codetask dev:gen- Generate code (mocks, ADTs)task dev:clean- Clean build artifactstask dev:go:update- Update Go dependencies
Database Operations
task db:ent:generate- Generate Ent models from schemastask db:ent:new -- ModelName- Create new Ent modeltask db:migrate:new- Generate migrations from schema changestask db:migrate- Apply pending migrationstask db:migrate:status- Show migration statustask db:migrate:create:blank -- MigrationName- Create blank migrationtask db:ent:lint- Lint migrationstask db:ent:hash- Hash migrationstask db:migrate:set-version -- VERSION- Set migration versiontask db:install:atlas- Install Atlas migration tool
Frontend
This tasks do usually not have to be called directly (they will be called by dev/build/package)
NO_COLOR=1 task common:install:frontend:deps- Install frontend dependenciesNO_COLOR=1 task common:build:frontend- Build frontend for production/developmentNO_COLOR=1 task common:generate:bindings- Generate Go-TypeScript bindingsNO_COLOR=1 task common:generate:icons- Generate app icons from source imageNO_COLOR=1 task common:update:build-assets- Update build assets with app info
Code Style Guide
- Error handling: Check errors with proper context message
- Naming: Use camelCase for variables, PascalCase for types in both Go and TypeScript
Backend
- Go: Use standard Go formatting/linting conventions
- Imports: Use alphabetical order for imports
- DB: Use Ent for database operations
- Folder structure: Do not use
internal/folder. As a Wails3 desktop app with no external importers, all backend code belongs inapp/
Frontend
- Imports: Group standard library, external, then internal imports
- Styles: Use Tailwind CSS with DaisyUI
- DaisyUI: Use the rules from https://daisyui.com/llms.txt
- Icons: Use Heroicons with
vite-plugin-iconsif possible - Syntax: Use await over then for promises
- Folder structure: frontend/bindings are generated with
task common:generate:bindings - Components: Use single file components with script setup and use the following convention:
<script setup lang='ts'> # ... add imports here /************ * Types ************/ # ... add types, enums, interfaces here /************ * Variables ************/ # ... add variables here /************ * Functions ************/ # ... add functions here /************ * Lifecycle ************/ # ... add lifecycle hooks, watchers, etc. here </script> <template> # ... add template here </template>
Service Architecture Patterns
Backend Services
- Service Structure: Use Service/ServiceRPC pattern for cloud-integrated services
Servicestruct: Contains business logic methods exposed to frontend and makes outgoing RPC calls to external cloud servicesServiceRPCstruct: Implements incoming Connect RPC server handlers for the service- Services use Connect RPC framework (not gRPC) for external cloud communication
- Initialization: Services are initialized with logger, state, and cloud RPC URL
- Database dependency is set later via
SetDb()method - Services registered in
app.goandcmd/root.go
- Database dependency is set later via
- Error Handling: Always wrap errors with context and log appropriately
- Background Monitoring: Use streaming RPC with timeout contexts and retry logic for long-running operations
- Implement configurable timeouts (e.g., 30 minutes) and retry intervals (e.g., 30 seconds)
- Use goroutines for background operations that survive UI state changes
- Clean up resources when operations complete or timeout
Protocol Buffers and Bindings
- Proto Changes: After modifying
.protofiles, always runtask proto:generate - Binding Updates: Generated TypeScript bindings are auto-created in
frontend/bindings/ - Response Handling: Use direct response properties (no
.dataor.Msgwrapper)
Frontend Integration
- Loading States: Add loading indicators for all external service calls
- Error Handling: Implement comprehensive error states with user-friendly messages
- Service Calls: Import services from generated bindings and handle nullable responses
- State Management: Use reactive refs for loading and error states
- Event Management: Use global event emission pattern without user/session parameters for state changes
- Store temporary session data in backend state with automatic cleanup
- Implement event listener cleanup arrays for proper resource management
Cloud Integration
- RPC Clients: Services communicate with cloud via Connect RPC clients
- Request/Response: Wrap requests with
connect.NewRequest()and handle response messages - Service Separation: Separate concerns into distinct services (auth, subscription, plan, etc.)
Linear
- Assignee: use "dev@uupi.cloud" for new issues
- Fix/Bugs: use "Bug" label
- Statuses: is one of ["Backlog", "Todo", "In Progress", "Code Review", "Done", "Canceled", "Duplicate"]