dayuse-vibes
Dayuse Vibe Coding Standards
This skill ensures that code generated for non-developers meets professional standards while remaining understandable.
Core Principles
When generating code, you MUST follow these rules:
- TypeScript only - All code must use strict TypeScript
- No
anytype - Theanytype is strictly forbidden - DDD Architecture - Organize code according to Domain-Driven Design
- Systematic testing - Every feature requires tests
- Mandatory linting - Code must pass ESLint and Prettier
- Zod validation - Validate external inputs with Zod
- Result Pattern - Use Result<T, E> instead of throw/catch
- Security by default - Security audit, authorization checks, and no hardcoded secrets
DDD Architecture
Organize code into 4 distinct layers:
src/
├── domain/ # Business logic (THE WHAT)
│ ├── entities/ # Business objects with identity
│ ├── value-objects/# Immutable objects without identity
│ ├── repositories/ # Data access interfaces
│ └── services/ # Complex business operations
│
├── application/ # Use Cases (THE HOW)
│ ├── use-cases/ # Unit business operations
│ └── dtos/ # Data Transfer Objects
│
├── infrastructure/ # Technical details (THE WHERE)
│ ├── repositories/ # DB/API implementations
│ ├── services/ # External services
│ └── persistence/ # DB configuration
│
└── interfaces/ # Entry points (THE WHO)
├── http/ # REST controllers
├── cli/ # CLI commands
└── events/ # Event handlers
Layer Rules
| Layer | Depends on | Contains |
|---|---|---|
| Domain | Nothing | Entities, Value Objects, Repository Interfaces |
| Application | Domain | Use Cases, DTOs |
| Infrastructure | Domain | Repository Implementations, External services |
| Interfaces | Application | Controllers, CLI, Event Handlers |
Strict TypeScript
Required Configuration
All projects must have the following in tsconfig.json:
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitReturns": true,
"noUncheckedIndexedAccess": true
}
}
Alternatives to the any Type
Instead of any |
Use | When |
|---|---|---|
any |
unknown |
Truly unknown type (requires Type Guard) |
any[] |
T[] |
Typed arrays |
any |
Specific interface | Known structure |
any |
Union types | Multiple possible types |
any |
Generic <T> |
Reusable components |
any |
Record<string, unknown> |
Object dictionaries |
Type Guard Pattern
function isUser(value: unknown): value is User {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
'name' in value
);
}
Validation with Zod
Use Zod to validate ALL external inputs:
import { z } from 'zod';
// Define the schema
const CreateUserSchema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
age: z.number().int().positive().optional(),
});
// Infer the TypeScript type
type CreateUserInput = z.infer<typeof CreateUserSchema>;
// Validate data
function validateInput(data: unknown): Result<CreateUserInput, ValidationError> {
const result = CreateUserSchema.safeParse(data);
if (!result.success) {
return err(new ValidationError(result.error.issues));
}
return ok(result.data);
}
Result Pattern
Never use throw/catch for business errors. Use the Result Pattern instead:
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
// Helpers
const ok = <T>(data: T): Result<T, never> => ({ success: true, data });
const err = <E>(error: E): Result<never, E> => ({ success: false, error });
// Usage
function createUser(input: CreateUserInput): Result<User, UserError> {
if (await userExists(input.email)) {
return err(new EmailAlreadyExistsError(input.email));
}
const user = new User(generateId(), input.name, input.email);
return ok(user);
}
// Consumption
const result = createUser(input);
if (!result.success) {
// Handle the error
return handleError(result.error);
}
// Use result.data
Security and Authorization (Zero Trust)
The AI must adopt a Zero Trust approach: never trust inputs or implicit state.
1. Systematic Authorization Checks
Every business action must verify WHO is performing it and whether they have the RIGHT to do so.
// ❌ BAD: Assumes the user has permission because they are authenticated
function deleteProject(projectId: string, user: User) {
return projectRepo.delete(projectId);
}
// ✅ GOOD: Explicit permission check (Business Logic)
function deleteProject(projectId: string, user: User): Result<void, AppError> {
const project = await projectRepo.findById(projectId);
// Ownership or role check
if (project.ownerId !== user.id && user.role !== 'ADMIN') {
return err(new UnauthorizedError("You do not have permission to delete this project"));
}
return projectRepo.delete(projectId);
}
2. No Hardcoded Secrets
NEVER write API keys, tokens, passwords, or certificates directly in code.
// ❌ FORBIDDEN
const API_KEY = "sk-1234567890abcdef";
// ✅ REQUIRED
const API_KEY = process.env.OPENAI_API_KEY;
3. Input Sanitization
Never insert raw user data into:
- HTML (XSS risk)
- SQL queries (SQL Injection risk)
- System commands (Command Injection risk)
Use Zod to validate the format and escaping libraries for display.
Testing with Vitest
Test Location
Place tests alongside source files:
src/domain/entities/
├── user.ts
└── user.test.ts
Test Structure
import { describe, it, expect, beforeEach } from 'vitest';
describe('User', () => {
describe('changeName', () => {
it('should update name when valid', () => {
// Arrange
const user = new User('1', 'John', email);
// Act
user.changeName('Jane');
// Assert
expect(user.name).toBe('Jane');
});
it('should return error when name too short', () => {
const user = new User('1', 'John', email);
const result = user.changeName('J');
expect(result.success).toBe(false);
});
});
});
Tests Required For
- All domain Entities and Value Objects
- All application Use Cases
- All public functions
- Edge cases and error handling
Linting
Commands to Run
Before completing ANY code task:
npm run lint # Check for issues
npm run lint:fix # Auto-fix issues
npm run format # Format with Prettier
npm run test # Run tests
Full Verification Script
npm run lint:fix && npm run format && npm run test
Code Generation Workflow
For each new feature:
1. Determine the Layer
- Pure business logic? ->
domain/ - Operation orchestration? ->
application/ - External integration? ->
infrastructure/ - Entry point? ->
interfaces/
2. Create with Proper Types
- Define interfaces first
- Use explicit types everywhere
- Never use
any - Validate inputs with Zod
3. Handle Errors with Result
- Define specific error types
- Return Result instead of throw
- Document error cases
4. Write Tests
- Create the test file alongside the source
- Test the happy path
- Test error cases
5. Verify Quality
npm run lint:fix && npm run format && npm run test
Naming Conventions
| Type | Convention | Example |
|---|---|---|
| Files | kebab-case | user-repository.ts |
| Classes | PascalCase | UserRepository |
| Interfaces | PascalCase | UserRepository |
| Functions | camelCase | createUser |
| Constants | SCREAMING_SNAKE | MAX_RETRY_COUNT |
| Types | PascalCase | CreateUserDTO |
| Zod Schemas | PascalCase + Schema | CreateUserSchema |
Additional Resources
For detailed guides, refer to:
- references/ddd-architecture.md - Complete DDD Patterns
- references/typescript-patterns.md - Alternatives to the any type
- references/testing-guide.md - Complete Vitest Guide
- references/linting-setup.md - ESLint/Prettier Configuration
- references/zod-validation.md - Validation with Zod
- references/result-pattern.md - Detailed Result Pattern
Quick Reference
ALWAYS:
✓ Strict TypeScript
✓ Explicit types everywhere
✓ Tests for all code
✓ Linter before finishing
✓ DDD structure
✓ Zod for external inputs
✓ Result for business errors
✓ Permission checks
NEVER:
✗ any type
✗ Skip tests
✗ Ignore linter errors
✗ Infrastructure logic in domain
✗ throw/catch for business errors
✗ Unvalidated data
✗ Hardcoded secrets/API keys
More from dayuse-labs/skills-portfolio
dayuse-pptx
Creates Dayuse-branded presentations (PPTX) with consistent visual identity and storytelling structure. Use when the user asks to create a presentation, deck, slides, pitch deck, roadmap, reporting, plan d'action, or any PPTX for Dayuse. Also use when user mentions "prez Dayuse", "deck Dayuse", "slides internes", "pitch hotel", or "presentation partenaire". Handles both external pitch decks and internal strategy/reporting presentations. Do NOT use for non-Dayuse presentations.
16php-dayuse
Use when building PHP applications with Symfony, Doctrine, and modern PHP 8.4+. Invoke for strict typing, PHPStan level 10, DDD patterns, PSR standards, PHPUnit tests, Elasticsearch with Elastically, and Redis/MySQL optimization.
16dayuse-commands
Run local development commands on the Dayuse.com project. Use when starting/stopping Docker, running PHP tests (PHPUnit), frontend tests, linting (PHPStan, CS-Fixer, ESLint), database migrations, Elasticsearch indexing, translations, or any inv task. All commands require pipenv and Docker.
10dayuse-mail
Use when a Twig template uses `reservationData` or `array<string, mixed>`, when a Twig template receives variables via `include` parameters, when a Notifier calls `$dto->__toArray()`, or when creating a new transactional email template `.dto.html.twig`.
7frontend-design-dayuse
Create production-grade frontend interfaces following the Dayuse brand identity and design system. This skill should be used when the user asks to "build a page", "create a component", "design a UI", "make a frontend", "build a landing page", "create a dashboard", or any frontend development task for Dayuse. Applies the official Dayuse color palette, typography (Manrope + MaisonNeue), border-radius conventions, shadow system, and animation patterns.
5dayuse app commands
Run local development commands on the Dayuse.com project. Use when starting/stopping Docker, running PHP tests (PHPUnit), frontend tests, linting (PHPStan, CS-Fixer, ESLint), database migrations, Elasticsearch indexing, translations, or any inv task. All commands require pipenv and Docker.
3