- Added ProjectTask entity with fields for name, description, budget, hour contingent, hourly rate, and total price. - Created ProjectTaskRepository with methods for querying tasks by project and user access. - Implemented ProjectTaskVoter for fine-grained access control based on user roles and project membership. - Developed ProjectTaskSecurityListener to enforce permission checks during task creation. - Introduced custom ProjectTaskProjectFilter for filtering tasks based on project existence. - Integrated ProjectTask management in the frontend with Vue.js components, including CRUD operations and filtering capabilities. - Added API endpoints for ProjectTask with appropriate security measures. - Created migration for project_tasks table in the database. - Updated documentation to reflect new module features and usage.
201 lines
7.3 KiB
Markdown
201 lines
7.3 KiB
Markdown
# myCRM - AI Agent Instructions
|
|
|
|
## Project Overview
|
|
Modern, modular CRM system built with Symfony LTS. Focus on security, UX, and extensibility with a native-app-like feel through heavy AJAX usage.
|
|
|
|
## Tech Stack
|
|
- **Backend**: Symfony (current LTS version) - PHP framework following best practices
|
|
- **Database**: MariaDB (unless specific reasons dictate otherwise)
|
|
- **Frontend**: Vue.js 3 with Composition API, bundled via Symfony Webpack Encore
|
|
- **UI Components**: PrimeVue (DataTable, Charts, Forms, Dialogs for professional CRM UI)
|
|
- **Authentication**: Symfony Security component with modern permission system (RBAC/Voter pattern)
|
|
- **API**: API Platform for RESTful APIs with auto-generated OpenAPI docs
|
|
- **Admin UI**: Custom Vue.js components (no EasyAdmin) for maximum flexibility
|
|
|
|
## Development Workflow
|
|
```bash
|
|
# Initial setup
|
|
composer install
|
|
php bin/console doctrine:database:create
|
|
php bin/console doctrine:migrations:migrate
|
|
npm install && npm run dev
|
|
|
|
# Run development (parallel terminals recommended)
|
|
symfony serve -d # Backend server on :8000
|
|
npm run watch # Encore: Hot reload for Vue.js changes
|
|
|
|
# Production build
|
|
npm run build # Minified assets for deployment
|
|
|
|
# Run tests
|
|
php bin/phpunit # Backend tests
|
|
npm run test:unit # Vue component tests (Vitest/Jest)
|
|
php bin/console doctrine:schema:validate
|
|
|
|
# Cache management
|
|
php bin/console cache:clear
|
|
APP_ENV=prod php bin/console cache:warmup
|
|
```
|
|
|
|
## Symfony-Specific Conventions
|
|
|
|
### Directory Structure (Symfony Standard)
|
|
```
|
|
/config - YAML/PHP configuration files, routes
|
|
/src
|
|
/Controller - HTTP controllers (keep thin, delegate to services)
|
|
/Entity - Doctrine entities (CRM: Contact, Company, Deal, Activity, User)
|
|
/Repository - Database queries
|
|
/Service - Business logic (pipeline calculations, lifecycle management)
|
|
/Security/Voter - Permission logic per entity
|
|
/Form - Form types for entities
|
|
/EventListener - Doctrine events, kernel events
|
|
/templates - Twig templates (base layout, embed Vue app)
|
|
/assets
|
|
/js - Vue.js components, composables, stores (Pinia)
|
|
/components - Reusable Vue components (ContactCard, DealPipeline)
|
|
/views - Page-level Vue components
|
|
/api - API client wrappers for API Platform endpoints
|
|
/styles - SCSS/CSS (scoped styles in Vue SFCs)
|
|
/migrations - Doctrine migrations (version controlled)
|
|
/tests - PHPUnit tests (backend), Vitest/Jest (frontend)
|
|
```
|
|
|
|
### Key Architectural Patterns
|
|
|
|
**Controllers**: Keep lean - validate input, call services, return JSON/HTML
|
|
```php
|
|
// Good: Delegate to service
|
|
return $this->json($contactService->createContact($request->toArray()));
|
|
```
|
|
|
|
**Services**: Inject dependencies via constructor, use interfaces for flexibility
|
|
```php
|
|
class ContactLifecycleService {
|
|
public function __construct(
|
|
private EntityManagerInterface $em,
|
|
private EventDispatcherInterface $dispatcher
|
|
) {}
|
|
}
|
|
```
|
|
|
|
**Entities**: Use Doctrine annotations/attributes, define relationships carefully
|
|
- Contact ↔ Company (ManyToOne/OneToMany)
|
|
- Contact ↔ Activities (OneToMany)
|
|
- Deal ↔ Contact (ManyToOne with Deal ownership)
|
|
|
|
**Security Voters**: Implement granular permissions per entity action
|
|
```php
|
|
// Example: ContactVoter checks if user can VIEW/EDIT/DELETE specific contact
|
|
protected function supports(string $attribute, mixed $subject): bool
|
|
```
|
|
|
|
**Vue.js Integration**: Symfony renders base Twig template, Vue takes over
|
|
- Twig template loads Vue app entry point via Encore
|
|
- API Platform provides REST endpoints, Vue consumes them
|
|
- State management: Pinia stores for global state (current user, permissions)
|
|
- Routing: Vue Router for SPA navigation within CRM modules
|
|
|
|
**API Pattern**: API Platform handles CRUD, custom endpoints for business logic
|
|
```php
|
|
// Custom API endpoint example
|
|
#[Route('/api/deals/{id}/advance-stage', methods: ['POST'])]
|
|
public function advanceStage(Deal $deal): JsonResponse
|
|
{
|
|
$this->denyAccessUnlessGranted('EDIT', $deal);
|
|
return $this->json($this->dealService->advanceToNextStage($deal));
|
|
}
|
|
```
|
|
|
|
**Vue Component Pattern**: Composables for API calls, components for UI
|
|
```javascript
|
|
// composables/useContacts.js
|
|
export function useContacts() {
|
|
const contacts = ref([])
|
|
const loading = ref(false)
|
|
|
|
async function fetchContacts() {
|
|
loading.value = true
|
|
const response = await fetch('/api/contacts')
|
|
contacts.value = await response.json()
|
|
loading.value = false
|
|
}
|
|
|
|
return { contacts, loading, fetchContacts }
|
|
}
|
|
```
|
|
|
|
### CRM Domain Logic
|
|
|
|
**Core Entities**:
|
|
- `Contact`: Person with lifecycle state (Lead → Qualified → Customer)
|
|
- `Company`: Organization linked to contacts
|
|
- `Deal`: Sales opportunity with pipeline stage, value, probability
|
|
- `Activity`: Interaction record (call, email, meeting, note)
|
|
- `User`: System user with role-based permissions
|
|
|
|
**Permission System**: Use Symfony Voters for fine-grained access
|
|
- Entity-level: Can user view/edit this specific contact?
|
|
- Module-level: Can user access Reports module?
|
|
- Action-level: Can user export data?
|
|
|
|
**API Modules**: Expose selected functionality via RESTful endpoints
|
|
- Authentication: JWT tokens or API keys
|
|
- Rate limiting: Consider API Platform's built-in support
|
|
- Documentation: OpenAPI/Swagger auto-generated
|
|
|
|
## Code Quality Standards
|
|
- Follow Symfony best practices and PSR-12
|
|
- Type hints everywhere (PHP 8.x features)
|
|
- Doctrine migrations for all schema changes (never alter DB manually)
|
|
- Services autowired and autoconfigured in `services.yaml`
|
|
- Environment variables for configuration (`.env`, `.env.local`)
|
|
|
|
## Testing Strategy
|
|
- Unit tests for services (PHPUnit)
|
|
- Functional tests for controllers (WebTestCase)
|
|
- Doctrine schema validation in CI
|
|
- Security: Test voter logic explicitly
|
|
|
|
## Frontend Architecture Details
|
|
|
|
**Encore Configuration**: `webpack.config.js` compiles Vue SFCs
|
|
```javascript
|
|
Encore
|
|
.addEntry('app', './assets/js/app.js') // Main Vue app
|
|
.enableVueLoader()
|
|
.enableSassLoader()
|
|
.enablePostCssLoader()
|
|
```
|
|
|
|
**PrimeVue Integration**:
|
|
- Install: `npm install primevue primeicons`
|
|
- Use DataTable for contact/deal lists with filtering, sorting, pagination
|
|
- Use Dialog/Sidebar for forms (better UX than full page forms)
|
|
- Use Chart components for pipeline analytics, revenue forecasts
|
|
- Theme: Customize PrimeVue theme to match brand (Sass variables)
|
|
|
|
**Vue Component Organization**:
|
|
- `ContactList.vue` - PrimeVue DataTable with filters, export (talks to `/api/contacts`)
|
|
- `ContactDetail.vue` - TabView with form, activity timeline, related deals
|
|
- `DealPipeline.vue` - Custom Kanban or PrimeVue OrderList (update via API Platform)
|
|
- `ActivityFeed.vue` - Timeline component with real-time updates
|
|
- `Dashboard.vue` - Chart.js via PrimeVue Chart for KPIs
|
|
|
|
**Authentication in Vue**: Pass Symfony user data to Vue via Twig
|
|
```twig
|
|
<div id="app"
|
|
data-user="{{ app.user|json_encode }}"
|
|
data-permissions="{{ user_permissions|json_encode }}">
|
|
</div>
|
|
```
|
|
|
|
## Next Steps for AI Agents
|
|
As code develops, update this file with:
|
|
1. PrimeVue theme customization (specific color palette, component overrides)
|
|
2. Custom Doctrine types or extensions in use
|
|
3. Mercure integration for real-time updates (if implemented)
|
|
4. Event-driven patterns (custom events for CRM workflows)
|
|
5. Background job processing with Symfony Messenger
|
|
6. Deployment strategy (Docker, traditional hosting)
|