This document summarizes the rules used to build this Job Search Portal so the same standards can be reused in future projects.
- Keep it simple: prefer KISS over clever abstractions.
- Avoid duplication: apply DRY where duplication is real and repeated.
- Do not overbuild: apply YAGNI for features not currently needed.
- One responsibility per class/component (SRP).
- Keep behavior predictable (Principle of Least Surprise).
- Favor readability and maintainability over micro-optimizations.
- Use layered architecture:
controller: HTTP request/response onlyservice+service/impl: business logic onlyrepository: data access onlydto: request/response payloads onlymapper: entity/document <-> DTO mappingconfig: Redis/Elasticsearch/Web/Jackson configexception: centralized error handling
- Never put business logic in controllers.
- Never expose persistence entities directly in API responses.
- Prefer constructor injection; avoid field injection.
- Keep MySQL model and Elasticsearch document concerns separate.
- Use Redis through Spring Cache annotations for common read paths (simple, maintainable).
- Use
Pageableinternally and return a frontend-friendly page DTO:content,page,size,totalElements/totalItems,totalPages,hasNext,hasPrevious,loadTimeMs
- Use Bean Validation for request DTOs.
- Keep APIs stable; if contract changes are required, document them clearly.
- Keep clean structure:
components: UI-only piecespages: page-level orchestration/stateservices: API access onlyutils/constants: shared helpers and defaults
- Do not call Axios directly in components/pages; call service functions only.
- Use a single Axios client instance (
baseURL, headers, timeout, normalized error handling). - Use
useState+useEffectfor state/data flow (simple and beginner-friendly). - Keep components small and focused; avoid monolithic pages.
- All forms must use explicit
<label>fields. - Job and application lists should render in table format.
- Use reusable pagination component for page navigation.
- Show user-friendly loading and error states.
- Add
PropTypesfor components receiving props. - Prefer
globalThisoverwindowfor global APIs.
- Use meaningful names for variables, methods, and components.
- Keep methods short; extract helpers only when clarity improves.
- Remove dead code and empty directories.
- Avoid large
if/elseladders and unnecessarybreak/continuecomplexity. - Keep lint/build warnings at zero for touched files.
- Refactor incrementally; do not rewrite the whole project unless required.
- Preserve user-facing behavior unless fixing a bug.
- Validate with build/test commands before finalizing changes.
- Commit scoped changes with clear commit messages.
- Do not mix unrelated backend/frontend changes in one commit when avoidable.
- Controllers are thin.
- Services are readable and testable.
- DTOs are used correctly.
- API calls are centralized in frontend services.
- Pagination works end-to-end.
- Redis cache paths are simple and correct.
- Elasticsearch code is isolated and readable.
- Forms have labels and actions are clear.
- No unresolved imports/lint errors.
- Project builds successfully.