This is a modular Swift iOS application with a Vapor backend server, using Tuist for project generation and mise for tool management.
# Weather Alerts App - Development Guidelines ## Project Overview This is a modular Swift iOS application with a Vapor backend server, using Tuist for project generation and mise for tool management. ## Tooling Stack ### Required Tools - **mise** (v2.x+): Tool version manager - manages Tuist and Trunk versions - **Tuist** (v4.104.6): Xcode project generator and dependency manager - **Trunk** (v1.3.4+): Universal linter for code quality - **Xcode**: iOS development IDE - **swift-openapi-generator**: OpenAPI code generation (located in `bin/`) ### Tool Installation ```bash # Install mise first (if not installed) curl https://mise.run | sh # Then install project tools via mise mise install ``` ## Project Structure ``` weather-alerts-app/ ├── Apps/ │ ├── WeatherAlertsApp/ # Main iOS app │ │ ├── Sources/ # App source code │ │ ├── Resources/ # Assets, storyboards, etc. │ │ └── Tests/ # App tests │ ├── WeatherAlertsServer/ # Vapor backend server │ │ ├── Sources/ │ │ └── Tests/ │ └── TestApp/ # Test harness app ├── Modules/ # Modular feature components │ └── <ModuleName>/ │ ├── Project.swift # Tuist project definition │ ├── Sources/ # Module source code │ │ └── <ModuleName>/ │ └── Tests/ # Module tests │ └── <ModuleName>Tests/ ├── Tuist/ # Tuist configuration │ ├── Package.swift # SPM dependencies │ ├── ProjectDescriptionHelpers/ # Shared Tuist helpers │ └── Templates/ # Module scaffolding templates └── Workspace.swift # Root workspace definition ``` ## Commands for Agent Development ### Project Generation ```bash # Generate main app Xcode workspace (opens in Xcode) make app # Generate without opening Xcode make app-no-open # Generate specific module workspace (opens in Xcode) make module name=<ModuleName> # Generate module without opening Xcode make module-no-open name=<ModuleName> # Scaffold and generate new module make new-module name=<ModuleName> # Install/update dependencies tuist install # Regenerate all projects after dependency changes tuist generate ``` ### Building Code ```bash # Build main app (fast, recommended) make build-app # Build specific module make build-module name=<ModuleName> # Or build via command line with xcodebuild xcodebuild -workspace WeatherAlertsApp.xcworkspace \ -scheme WeatherAlertsApp \ -destination 'platform=iOS Simulator,name=iPhone 16 Pro' \ build ``` ### Linting ```bash # Lint changed files only (fast, recommended for development) trunk check --ci # Lint all files trunk check --all --ci # Auto-fix issues where possible trunk check --fix --ci # Lint specific files or directories trunk check --ci path/to/file.swift # Lint with specific linters only trunk check --ci --filter=swiftlint,swiftformat ``` ### Testing ```bash # Test main app (fast, recommended) make test-app # Test specific module make test-module name=<ModuleName> # Or use xcodebuild directly xcodebuild test \ -workspace WeatherAlertsApp.xcworkspace \ -scheme WeatherAlertsApp \ -destination 'platform=iOS Simulator,name=iPhone 16 Pro' # Or use Xcode UI: Cmd+U to run tests ``` ### Running the Server ```bash # Run server via SPM (recommended) make spm-server name=WeatherAlertsServer # Run server via Tuist make tuist-server name=WeatherAlertsServer # Set log level make spm-server name=WeatherAlertsServer LOG_LEVEL=info ``` ### Docker (Server) ```bash # Build server image docker compose build # Start server with Postgres database docker compose up app # Stop all services docker compose down ``` ### Code Generation ```bash # Regenerate WeatherAPI from OpenAPI spec cd Modules/WeatherAPI ./generate_code.sh # Generate Cuckoo mocks make mocks ``` ### Cleanup ```bash # Clean Tuist cache and derived data make clean tuist clean # Nuclear clean (WARNING: removes all untracked files except Tuist build cache) make very-clean ``` ## Development Workflow ### Creating a New Module 1. Scaffold the module: `make new-module name=MyModule` 2. Implement features in `Modules/MyModule/Sources/MyModule/` 3. Add tests in `Modules/MyModule/Tests/MyModuleTests/` 4. Add module dependency to main app in `Apps/WeatherAlertsApp/Project.swift` if needed 5. Regenerate main app: `make app` ### Making Changes to Existing Code 1. Ensure workspace is generated: `make app` or `make module name=<ModuleName>` 2. Open the appropriate `.xcworkspace` file in Xcode (or use `make app-no-open` to skip opening) 3. Make changes to Swift files 4. Lint changes: `trunk check --ci` 5. Build: `make build-app` or `make build-module name=<ModuleName>` 6. Run tests: `make test-app` or `make test-module name=<ModuleName>` 7. Fix any linter errors: `trunk check --fix --ci` ### Adding Dependencies 1. Add package to `Tuist/Package.swift` for SPM dependencies 2. Or add to `Tuist/ProjectDescriptionHelpers/PackageDependencies.swift` for Tuist-managed packages 3. Update module's `Project.swift` to include the dependency 4. Run `tuist install` to fetch dependencies 5. Regenerate projects: `tuist generate` or `make app` ### Before Committing 1. Run linter: `trunk check --all --fix --ci` 2. Build: `make build-app` (or `make build-module name=<ModuleName>` for modules) 3. Run tests: `make test-app` (or `make test-module name=<ModuleName>` for modules) 4. Ensure no build errors or warnings 5. Clean up any generated files not meant for version control ## Code Style Guidelines ### Swift Best Practices - Use declarative and composable patterns - Avoid inheritance; prefer protocols and composition - Avoid mutable patterns; prefer immutability - Use Swift concurrency (async/await, actors) over legacy GCD - No trailing whitespace at end of lines ### Project Conventions - Each module should be focused and have a single responsibility - Keep module dependencies minimal and explicit - Use dependency injection - Place shared utilities in dedicated modules (e.g., LoggingService, RESTService) - Test coverage expected for all modules ## Key Dependencies ### iOS App (in Tuist/Package.swift) - `swift-openapi-runtime`: OpenAPI client support - `swift-openapi-urlsession`: URLSession transport for OpenAPI - `ViewInspector`: SwiftUI testing - `swift-snapshot-testing`: Snapshot tests - `swift-concurrency-extras`: Concurrency utilities - `Cuckoo`: Mock generation ### Server - `Vapor`: Web framework - `swift-nio`: Networking ## Troubleshooting ### "No such workspace" errors - Run `make app` to generate the workspace first - Workspaces are not checked into git and must be generated locally ### Xcode build errors after pulling changes - Run `tuist clean && tuist install && make app` - Kill Xcode and regenerate: `make app` (includes kill-xcode step) ### Linter not found - Ensure mise is installed: `mise --version` - Install tools: `mise install` ### Module not found in main app - Add module to dependencies in `Apps/WeatherAlertsApp/Project.swift` - Regenerate app workspace: `make app` ## Important Notes for Agents 1. **Always generate projects before building**: Run `make app` or `make module name=<ModuleName>` before attempting to build 2. **Never commit generated files**: `.xcworkspace` and `.xcodeproj` files are generated by Tuist, not source 3. **Lint before testing**: Run `trunk check` to catch issues early 4. **Use Make targets**: Prefer `make` commands over direct `tuist` calls for common operations 5. **Module isolation**: Each module should be independently testable and buildable 6. **Tool versions matter**: Use mise-managed tool versions specified in `mise.toml`
Comprehensive .cursorrules file for Next.js 15 App Router projects with TypeScript, enforcing server components by default, proper use of "use client" directive, and App Router conventions.
Cursor rules for Python FastAPI projects enforcing async patterns, Pydantic v2 models, dependency injection, and proper error handling.
Rules for consistent React component development with TypeScript interfaces, proper hook patterns, and component composition.
Rules optimizing Cursor Agent mode behavior including multi-file editing context, session management, and autonomous task completion patterns.
Cursor rules for projects using Tailwind CSS with shadcn/ui component library, enforcing consistent utility class usage and component patterns.
Rules for Go backend services enforcing idiomatic Go patterns, proper error handling, and clean architecture conventions.