Project documentation#268
Open
Awakich wants to merge 24 commits into
Open
Conversation
aliases, application layering, cross-cutting blocks, environments,
prod/dev-stage cookie isolation, build/CI, routing entry points,
kanban-disabled note, planned per-module docs index).
- Replace root README stub (Angular CLI 13 leftover) with a short
pointer to docs/.
Add docs/core/ with five files covering all of projects/core/src: - services.md: 11 services with full method tables, behaviour notes, known bugs (LoggerService PRODUCTION DI token mismatch, ErrorService throwNotFount typo, unused deps in GlobalErrorHandlerService) and architectural debt (core depends on social_platform). - interceptors-providers.md: BearerToken (refresh flow, blob handling, parallel-401 dedup), Camelcase (FormData passthrough), Logging; the three InjectionTokens; missing WEBSOCKET_* tokens. - pipes.md: 16 pipes in one table; DayjsPipe action types; pipes/index.ts gaps. - guards-models.md: 3 active guards (kanban guard noted as disabled); ErrorCode, ErrorMessage (full text table), ApiError, subscription models. - consts.md: folder layout, naming rules (moved from deleted README), every list/filter/navigation/other constant tabulated with kanban-only tags; "how to add a new constant" guide. Mark the five core/ docs as done in docs/PROJECT.md index. Drop README stubs: - projects/core/README.md (superseded by docs/core/*) - projects/core/src/consts/README.md (naming rules folded into docs/core/consts.md) No source changes. JSDoc/inline comments will be a separate phase.
Add docs/uilib.md covering all of projects/ui/src: - Folder layout, exports through public-api, and the discrepancy between the uilib alias surface (only ./lib/components) and what consumers actually need (User model is reachable only by deep import). - Component table with selector, kind, all inputs/outputs. - Per-component sections for layout (Sidebar, ProfileControlPanel, ProfileInfo, InviteManageCard, EmptyManageCard) and primitives (Avatar, Back, IconComponent attribute directive with appSquare/ appViewBox/appWidth/appHeight behaviour). - NavItem interface for SidebarComponent. - User model + note that it duplicates social_platform/domain/auth/user.model. - Architectural debt: ui-sidebar selector inconsistency, EmptyManageCard not re-exported, User duplication, uilib/models alias mismatch, AvatarComponent url required vs optional type. Mark docs/uilib.md as done in docs/PROJECT.md index. Drop projects/ui/README.md - superseded. No source changes.
Add docs/social-platform/architecture.md covering everything in projects/social_platform/src/app/: - Folder layout per layer (domain / api / infrastructure / ui). - Dependency rules and the boundary every layer must respect. - domain/ - abstract-class ports vs interfaces, why and how. - api/ - use-cases (one execute method, returns Result), facades (signal AsyncState), UI-info services (computed-only). - infrastructure/ - repositories with EntityCache, HTTP adapters, per-module DI providers binding ports to implementations. - ui/ - routes/pages/widgets/primitives/services split. - utils/ - full inventory with kanban-only tags. - Cross-cutting building blocks: AsyncState, Result, toAsyncState, EventBus, EntityCache, LoggingInterceptor + LoggerService, GlobalErrorHandler. - app.config.ts breakdown: provider order, HTTP interceptor stack, per-module DI sets. - Actual HTTP interceptor order (Camelcase, Bearer, Logging) with rationale; corrects the inaccurate ordering note in docs/core/interceptors-providers.md. - Import conventions: alias table, no deep cross-project imports. - Naming and structural conventions. - Entry points: main.ts, app.component, app.config, app.routes. Mark docs/social-platform/architecture.md as done in docs/PROJECT.md index. Drop projects/social_platform/README.md - it described the pre-refactor structure (auth/, office/projects/list, office/chat, office/feed, office/members, etc.) which moved into ui/pages/... in commit be9344b; nothing salvageable. No source changes.
Add docs/social-platform/shared.md covering the cross-module pieces of projects/social_platform/src/app: - domain/shared/: AsyncState (full discriminator + helpers + type guards + previous semantics), Result (ok/fail), toAsyncState operator, EntityCache (getOrFetch/invalidate/clear with shareReplay), EventBus (emit/on with auto-debug logging), DomainEvent base contract. - domain/file/: FileModel. - domain/other/: ApiPagination, FilterFieldConfig + FilterConfig + UnifiedOption, Navigation, Notification. - utils/: full inventory of all 21 helpers with signature, behaviour and call-site notes; explicit kanban-only tags on getActionType / getPriorityType. - Architectural debt list: typos (days-untit, maxAttemps), under-typed any returns (inviteToProjectMapper, FilterFieldConfig), duplicate breakpoint definitions, EntityCache non-null assertion, etc. Mark docs/social-platform/shared.md as done in docs/PROJECT.md index. No source changes.
Add docs/social-platform/ui-primitives.md and ui-widgets.md covering all 22 atoms in projects/social_platform/src/app/ui/primitives/ and all 20 widgets in projects/social_platform/src/app/ui/widgets/: - ui-primitives.md: full input/output table for every primitive, CVA marker, defaults; per-component notes for IconComponent attribute directive, ModalComponent open setter, DropdownComponent with kanban coupling note, AutoCompleteInputComponent generics, CVA list. Architectural debt around dropdown-kanban coupling, AvatarComponent.url required-but-optional, missing index.ts entries. - ui-widgets.md: input/output/usage table for every widget; per-widget notes for DeatilComponent (universal detail header for project/ program/profile, smart-but-classified-as-widget), InfoCardComponent type polymorphism, ChatWindow + MessageInput pair, filter widgets (no inputs, work via own services and query params), NewsForm + NewsCard pair, skill triad (group/spec/basket), ProjectNavigation stepper, HeaderComponent, CookieConsent. Architectural debt around DeatilComponent / InfoCardComponent typos (kept on purpose), filter widgets being smart, Output type shadowing TS keyword, etc. Mark both docs as done in docs/PROJECT.md index. Drop projects/social_platform/src/app/ui/README.md - it described form/select/input components in flat text without inputs/outputs and mentioned RangeInput/NumSlider that no longer exist; superseded by the two docs above. No source changes.
Add docs/modules/auth.md covering the auth vertical: - domain/auth: User (mega-class with role branches and subscription), Achievement / Education / WorkExperience / UserLanguages / UserRole, Tokens, LoginResponse / RefreshResponse / RegisterResponse, RegisterRequest, PasswordValidationErrors. Commands (LoginCommand, RegisterCommand) and discriminated-union Results (LoginError, RegisterError with validation_error fan-out, PasswordError). - api/auth/use-cases: LoginUseCase, RegisterUseCase, ResendEmailUseCase, ResetPasswordUseCase, SetPasswordUseCase, DownloadCvUseCase - all return Result<T, E> with full error mapping. - api/auth/facades: AuthInfoService (root, holds profile/roles streams), AuthUIInfoService (page-scoped, all forms + signal AsyncState), AuthLoginService, AuthRegisterService, AuthPasswordService, AuthEmailService (with countdown timer + magic-link handling). - api/auth/profile.service.ts: legacy CRUD for achievements + skill approval, marked as architectural debt. - infrastructure/repository/auth: AuthRepository with three ReplaySubject streams, plainToInstance(User) on every payload. - infrastructure/adapters/auth: full HTTP endpoint table for /api/token, /auth, /auth/users surfaces. - ui/routes/auth: lazy AUTH_ROUTES with /verification handled outside the AuthComponent shell to support magic-link tokens in query. - ui/pages/auth: AuthComponent layout + 7 child pages (login, register, email-verification, confirm-email, reset-password, set-password, confirm-password-reset) with their facades and providers. - Consumers section: who outside the module touches the port. - Known issues: core depending on domain/auth, ?adress= typo kept on purpose, saveAvatar trailing-slash, narrow unknown error in Resend/Reset use-cases, Achievement.files polymorphism, etc. Mark docs/modules/auth.md as done in docs/PROJECT.md index. Drop projects/social_platform/src/app/ui/pages/auth/README.md - the component descriptions there are flat-text without inputs/outputs and duplicate the new doc. No source changes.
Add docs/modules/profile.md covering the profile vertical:
- domain/profile: ProfileNews model + ProfileNewsRepositoryPort.
Profile (User) edit relies on AuthRepositoryPort - no separate port.
- api/profile/use-cases: 7 news use-cases (Fetch/GetDetail/Add/Edit/
Delete/ToggleLike/Read). ReadProfileNewsUseCase de-dupes through
StorageService(sessionStorage[readNews]).
- api/profile/facades:
- detail: ProfileDetailInfoService, ProfileDetailUIInfoService
(user signal, isProfileEmpty/Fill, directions for direction-card,
isShowModal), ProfileDetailProjectsInfoService.
- edit: ProfileFormService (root, holds the FormGroup), plus 5
page-scoped facades (Main/Education/Experience/Skills/
Achievements) coordinated by ProfileEditInfoService with step
routing, userTypeMap for role branches, error modals.
- infrastructure/repository/profile: ProfileNewsRepository with
plainToInstance + readNews session-storage cache.
- infrastructure/adapters/profile: HTTP endpoint table for
/auth/users/<id>/news/* surface.
- infrastructure/di: PROFILE_NEWS_PROVIDERS.
- ui/routes/profile: PROFILE_DETAIL_ROUTES with ProfileDetailResolver
(forkJoin user + calculateProfileProgress) and ProfileMainResolver
(news detail).
- ui/pages/profile:
- detail: ProfileMainComponent split into left/mid/right side
components, ProfileNewsComponent for /news/:newsId.
- edit: ProfileEditComponent with five step-components
(main / education / experience / skills / achievements),
integrated through <app-project-navigation> stepper.
- Edit flow walkthrough: from Edit click to updateProfile() with
the dayjs/phoneNumber TODO cross-references to merge memory.
- Consumers and known issues (edit flow split across facades,
legacy ProfileService coupling, missing profile.repository.port,
ProfileMainResolver naming).
Mark docs/modules/profile.md as done in docs/PROJECT.md index.
No source changes.
Add docs/modules/skills.md covering the technical-skills vertical:
- Disambiguation up front: this module = /core/skills/* under the
main API (programming, design, etc.), separate from
SkillsApiService / SubscriptionPlansService which lives under
SKILLS_API_URL for the subscription/payments domain.
- domain/skills: Skill (with Approve[] confirmations chain),
SkillsGroup (category -> skills), SkillsRepositoryPort.
- api/skills/use-cases: GetSkillsNestedUseCase, SearchSkillsUseCase
- both collapse all errors into { kind: server_error }.
- api/skills/facades: SkillsInfoService (root) - holds inlineSkills
signal for autocomplete, exposes onAddSkill/onRemoveSkill/
onToggleSkill helpers that mutate a passed FormGroup
(deliberate: skills widgets are dumb, the FormGroup mutation
is concentrated here).
- infrastructure/repository/skills: thin SkillsRepository passthrough
with no EntityCache (note as debt - a single nested list is
refetched on every consumer subscription).
- infrastructure/adapters/skills: HTTP endpoint table for
/core/skills/nested and /core/skills/inline (with
name__icontains query and limit/offset pagination).
- Skills widgets <app-skills-group> / <app-skills-basket>
consumption: inputs/outputs and where they are wired.
- Consumers list across profile-edit, project-edit (vacancy step),
members-filters, onboarding stage-two, and (disabled) kanban
task-detail.
- Known issues: missing shareReplay on getSkillsNested,
onSearchSkill hard-codes limit=1000, SkillsInfoService bypasses
use-cases, approve/unapprove still on legacy ProfileService.
Mark docs/modules/skills.md as done in docs/PROJECT.md index.
No source changes.
Add docs/modules/specializations.md covering the specializations vertical: - Disambiguation: specializations = role/profession (Frontend dev, Designer, PM), distinct from skills (technical know-how). - domain/specializations: Specialization (id+name), SpecializationsGroup (group+specializations[]), SpecializationsRepositoryPort (nested + inline search with limit/offset/name__icontains). - No use-cases - facade goes straight to the port. Marked as debt vs the parallel skills module which already has use-cases. - api/specializations/facades: SpecializationsInfoService (root), pure passthrough. - infrastructure/repository/specializations: thin pass-through repo without EntityCache or class-transformer. - infrastructure/adapters/specializations: HTTP endpoint table for /auth/users/specializations/nested and /inline (note that specializations sit under auth/users on the backend). - Widget <app-specializations-group> reference back to ui-widgets doc. - Consumers: profile-edit (ProfileFormService.inlineSpecs), onboarding stage-one, members search through api/searches. - Known issues: missing use-cases, missing shareReplay, passthrough facade adds no value yet. Mark docs/modules/specializations.md as done in docs/PROJECT.md index. No source changes.
Add docs/modules/industry.md for the industries reference (IT, Fintech, Education, Urbanism, etc.) used to classify projects, vacancies, programs: - domain/industry: Industry (id+name) and IndustryRepositoryPort with a Signal industries cache exposed alongside getAll() + synchronous getOne(id). - No use-cases; facade is a thin passthrough (debt vs skills). - api/industry/facades: IndustryInfoService re-exports the signal and the two repository methods. - infrastructure/repository/industry: IndustryRepository fills the signal in tap() of getAll(), runs plainToInstance, has an unused EntityCache<Industry> (debt - dead code). - infrastructure/adapters/industry: single endpoint GET /industries/ returning the full flat list (no pagination/search on backend). - Consumers: project detail, feed (new-project, open-vacancy), program rating-card, info-card widget, projects-filter, office shell (warms the cache), project edit form. - Known issues: missing use-cases, passthrough facade, dead EntityCache, getOne(id) returns undefined synchronously when cache is empty (callers must dispatch getAll() first). Mark docs/modules/industry.md as done in docs/PROJECT.md index. No source changes.
Add docs/modules/member.md for the platform participants list:
- Disambiguation: member = User with userType === 1; userType 2/3/4
are mentor/expert/investor and use a parallel getMentors()
endpoint with user_type=2,3,4 filter.
- domain/member: only the MemberRepositoryPort - no own model
(reuses User from auth).
- api/member/use-cases: GetMembersUseCase (Result with
get_members_error). getMentors has no use-case yet.
- api/member/facades:
- MembersInfoService (page-scoped) - reactive search and
filter forms, debounce, infinite scroll on container
scroll, query-param sync.
- MembersUIInfoService (page-scoped) - members$ AsyncState
signal with previous-during-loading semantics, members
computed, totalCount, take, page, searchForm, filterForm
(keySkill, speciality, age range, isMosPolytechStudent).
- MentorsUIInfoService - dead code, no consumer.
- infrastructure/repository/member: pass-through with
plainToInstance(User).
- infrastructure/adapters/member: GET /auth/public-users/ with
user_type discriminator and limit/offset/filter params.
- Routes attached inside office shell, no separate members.routes.
- Pages: MembersComponent + MembersFiltersComponent (autocomplete
for key skill and speciality through skills/searches).
- Resolver MembersResolver fetches the first 20.
- Consumers: info-card with type=members, project-team-step.
- Known issues: dead MentorsUIInfoService, missing GetMentorsUseCase,
filterForm.keySkill/speciality marked required by mistake,
untyped Record<string, ...> filter params.
Mark docs/modules/member.md as done in docs/PROJECT.md index.
No source changes.
Add docs/modules/project.md - the largest module: 8 sub-domains
across ports/repos/DI, 33 use-cases, 14+ facades for the edit flow,
9 repositories, 8 HTTP adapters, multiple page hierarchies.
- domain/project: Project mega-model (with PartnerProgramInfo,
ProjectCount, ProjectStep), Collaborator, Goal+ResponsibleInfo,
Partner+PartnerDto+Company, Resource+ResourceDto, ProjectAssign,
ProjectAdditionalFields, ProjectSubscriber, the 4 rating models,
step.model and the 4 wrapper-types around skills/specializations.
- domain/project/commands: UpdateFormCommand.
- domain/project/events: ProjectCreated, ProjectDeleted,
ProjectSubscribed, ProjectUnSubscribed (sic), and
RemoveProjectCollaborator.
- 9 repository ports: project, collaborators, goals, news, partner,
program (assign-to-program + send-fields), rating, resource,
subscription. Methods enumerated in tables.
- 33 use-cases tabulated by responsibility: list/get/create/delete,
goals CRUD, partners CRUD, resources CRUD, subscribers,
subscriptions add/delete (event-emitting), 7 news use-cases,
competitive-submission, additional-fields, leave/remove-collab.
- api/project/facades: list / dashboard / detail (with sub-tabs:
info, work-section, chat) / edit. Edit flow detail: ProjectFormService
(root) + ProjectFormFactory + ProjectFormAutosaveService and 8
step-specific services (Main/Contacts/Achievements/Goals/
Partner+Resources/Vacancy/Team/Additional).
- ProjectRepository: showcase of EventBus + EntityCache - listens
to its own ProjectCreated/Deleted/Subscribed/Unsubscribed and
RemoveProjectCollaborator events plus the three vacancy-response
events to invalidate the cache automatically.
- HTTP endpoint table grouped by adapter (project, collaborators,
goals, news, partner, program, rating, resource).
- Routes: PROJECTS_ROUTES (dashboard/my/all/subscriptions/invites/
edit at root) and PROJECT_DETAIL_ROUTES (info/news/vacancies/
team/work-section/chat) with the kanban route explicitly noted
as commented-out.
- Pages: full inventory across detail/info three-column layout,
detail/{vacancies,team,work-section,chat,news-detail}, edit
with 6 step components.
- Consumers and known issues: typos kept (projecId, UnSubscribed),
duplicate domain wrapper types, legacy ProjectsService alongside
use-cases, edit-flow facade sprawl, autosave with no retry queue.
Mark docs/modules/project.md as done in docs/PROJECT.md index.
No source changes.
Add docs/modules/vacancy.md covering vacancies + responses: - domain/vacancy: Vacancy (with project + requiredSkills + salary string + work format/schedule), VacancyResponse (whyMe + isApproved + accompanyingFile), VacancyRepositoryPort with 11 methods. - 6 domain events: VacancyCreated/Updated/Delete (sic) plus SendVacancyResponse / AcceptVacancyResponse / RejectVacancyResponse consumed by ProjectRepository for cache invalidation. - 10 use-cases: GetVacancies, GetVacancyDetail, GetMyVacancies, PostVacancy (emits Created), UpdateVacancy (emits Updated), DeleteVacancy (emits Delete), SendVacancyResponse (emits Send), GetProjectResponses, AcceptResponse / RejectResponse with their events. - Facades: VacancyInfoService + VacancyUIInfoService for the list page (search/filter forms with debounce + query-param sync, infinite scroll, listType all/my), VacancyDetailInfoService + VacancyDetailUIInfoService for detail page (sendForm with ValidationService, ExpandService for description, modal state). - Repository: pass-through with plainToInstance + EntityCache, EventBus subscriptions for own VacancyCreated/Updated/Delete (note: VacancyCreated invalidates by projectId while cache keys by vacancyId - probable bug). - HTTP endpoint table for /vacancies/* and /projects/<id>/responses surfaces. - Routes: VACANCIES_ROUTES (all + my + detail), VACANCY_LIST_ROUTES (my), VACANCIES_DETAIL_ROUTES. - Pages: VacanciesComponent shell, VacanciesListComponent (shared for all/my, switches by URL), VacanciesDetailComponent + VacancyInfoComponent + left/right side, ResponseCardComponent. - Resolvers VacanciesResolver / VacanciesMyResolver / VacanciesDetailResolver. - Widgets <app-vacancy-card>, <app-project-vacancy-card>, <app-vacancy-filter> referenced back to ui-widgets doc. - Consumers: project-edit vacancy-step, project-detail vacancies/work-section, feed/open-vacancy, info-card. - Known issues: VacancyDelete naming asymmetry, salary-as-string, CreateVacancyDto living in api/project/dto, no listType @input in VacanciesListComponent, etc. Mark docs/modules/vacancy.md as done in docs/PROJECT.md index. No source changes.
Add docs/modules/invite.md covering project invitations: - domain/invite: Invite (project + role + specialization + motivationalLetter + isAccepted + user/sender), two commands (SendForUserCommand, UpdateInviteCommand), three domain events (AcceptInvite/RejectInvite/RevokeInvite) all with factory functions. - InviteRepositoryPort with 7 methods. - 7 use-cases: SendForUser, RevokeInvite (emits Revoke), AcceptInvite (emits Accept), RejectInvite (emits Reject), UpdateInvite, GetMyInvites, GetProjectInvites. - Repository: pass-through with plainToInstance, plus myInvitesCount$ BehaviorSubject decremented on AcceptInvite / RejectInvite events for the header badge. - HTTP endpoint table for /invites/* surface, including the ?user=any sentinel in getByProject. - No own routes or pages - invites are surfaced through the header dropdown (uilib's app-profile-control-panel + app-invite-manage-card), in pages/projects/list?type=invites, and inside pages/projects/edit project-team-step. - Widgets cross-reference: app-invite-manage-card (uilib), app-info-card with type=invite. - Consumers across project-edit team-step, projects list, inviteToProjectMapper util. - Known issues: RevokeInvite event has no listener, AcceptInvite does not invalidate ProjectRepository (asymmetric vs RemoveProjectCollaborator), myInvitesCount$ has no push-update, inconsistent trailing slashes, ?user=any sentinel parameter, port-vs-adapter type mismatch on revokeInvite return type. Mark docs/modules/invite.md as done in docs/PROJECT.md index. No source changes.
Add docs/modules/program.md covering partnership programs: - domain/program: Program (full set of dates - registration ends, start, finish, project submission, evaluation; isUserManager / isUserMember flags; courses[] back-reference, registrationLink, materials[]), ProgramDataSchema (key-value config), ProgramTag. - partner-program-fields.model: PartnerProgramFields (dynamic form fields per program), PartnerProgramFieldsValues, ProjectNewAdditionalProgramFields with snake_case quirks. - ProgramRepositoryPort (13 methods including the submitCompettetiveProject typo) + ProgramNewsRepositoryPort. - 22 use-cases: GetPrograms / GetActualPrograms / GetProgram / Register / GetDataSchema / GetProgramFilters / CreateProgramFilters / GetAllProjects / GetAllMembers / ApplyProjectToProgram / AssignProjectProgram / ParticipatingProgram / GetProjectRatings / FilterProjectRatings / RateProject and 6 news use-cases (FetchNews / AddNews / EditNews / DeleteNews / ReadNews / ToggleLike). - Facades: ProgramInfoService (root), ProgramMainInfoService + UI for the all-programs list, ProgramDetailMainService + UI for the detail main page, ProgramDetailListInfoService + UI for the polymorphic projects/members/rating list. - Repositories: pass-through with EntityCache for getOne; program-news with StorageService de-dup like profile/project. - Two HTTP endpoint tables for /programs/* and /programs/<id>/news/*. - Routes: PROGRAM_ROUTES (all + lazy detail), PROGRAM_DETAIL_ROUTES (main / projects / members / projects-rating + register outside the DeatilComponent shell). - Pages: ProgramComponent shell, ProgramMainComponent + ProgramCardComponent, ProgramDetailMainComponent, ProgramListComponent (polymorphic by listType), ProgramProjectsFilterComponent, RatingCardComponent + ProjectRatingComponent for expert evaluation, ProgramRegisterComponent with dynamic form from data schema. - Resolvers wired per route. - Widgets cross-reference: app-detail (program mode), app-program-links, app-news-card, app-news-form, app-info-card type=rating. - Consumers: project-edit additional-step (program fields), project-detail (partnerProgram), course-detail (partnerProgramId), widgets/detail, User.programs. - Known issues: Cmpettetive typo, untyped applyProjectToProgram, snake_case in ProjectNewAdditionalProgramFields, value_text named text but holds bool too, Program.tag string vs ProgramTag class inconsistency, news duplicating profile/project structures (candidate for unified domain/news/). Mark docs/modules/program.md as done in docs/PROJECT.md index. No source changes.
Add docs/modules/courses.md covering courses + lessons + tasks:
- domain/courses: full type tree CourseCard / CourseDetail /
CourseStructure / CourseModule / CourseLessons / CourseLesson /
Task / Option / TaskAnswerResponse, with status / progressStatus
/ actionState / accessType union types.
- Task answer types tabulated: text, text_and_files, single_choice,
multiple_choice, files, informational - each mapped to the
corresponding lesson/shared/* component.
- TaskAnswerSubmitted domain event listened by ProjectRepository.
- Two ports: CoursesRepositoryPort (HTTP) and SeenModulesStoragePort
(the only non-HTTP port - localStorage-backed flag for the
"module completed" celebration modal, key
course_<courseId>_module_<moduleId>_complete_seen).
- 5 use-cases: GetCourses, GetCourseDetail, GetCourseStructure,
GetCourseLesson, SubmitTaskAnswer (emits TaskAnswerSubmitted).
- Facades:
- CoursesListInfoService + UI for the all-courses list.
- CourseDetailInfoService + UI - parallel detail+structure fetch
via forkJoin in resolver, applyCourseData triggers the
seen-modules check, redirectToProgram for the back-link.
- LessonInfoService + UI - per-lesson controller with
currentTaskId/activeTaskId, completedTaskIds Set,
isDone/isClickable/isViewingCompleted helpers,
lessonOrder computed via injected CourseDetailUIInfoService
(DI hierarchy parent-child).
- Repository: pass-through with two EntityCaches (detail and
structure separately). postAnswerQuestion emits
TaskAnswerSubmitted via EventBus.
- HTTP endpoint table for /skills/courses/* and /skills/lessons/*
and /skills/tasks/* surface (note: /skills prefix is legacy,
the skills sub-project itself is removed).
- Routes: COURSES_ROUTES (all + lazy detail), COURSE_DETAIL_ROUTES
(info + lazy lesson) with runGuardsAndResolvers: always,
LESSON_ROUTES (single :lessonId + /results child).
- Pages: CoursesListComponent, CourseDetailComponent (provides
the detail+structure pair), CourseInfoComponent with
CourseModuleCard + CircleProgressBar, LessonComponent (provides
LessonInfoService + LessonUIInfoService and renders the right
task component conditionally), TaskCompleteComponent for results,
five lesson task components.
- Widget cross-reference: app-course-about.
- Consumers: program (Program.courses[] back-reference), widgets/detail
for course-program navigation, ProjectRepository listening for
TaskAnswerSubmitted.
- Known issues: /skills URL legacy, Task.answerType not unioned,
analyticsStub: any placeholder, app-detail selector conflict in
CourseInfoComponent vs widget, SeenModulesStoragePort sync API
doc, lessonOrder missing on the API payload, lessonId smuggled
into the use-case via facade rather than command.
Mark docs/modules/courses.md as done in docs/PROJECT.md index.
No source changes.
Add docs/modules/news.md as a cross-cutting overview that ties together the four news shapes used in the app: - domain/news/article.model.ts: New class (singular - despite the filename being article) used for marketing articles in feed. Cross-references the three feature-owned news domains: - project-news (in docs/modules/project.md) - profile-news (in docs/modules/profile.md) - program-news (in docs/modules/program.md) - api/news/news-info.service.ts: shared root-provided NewsInfoService with news$ AsyncState signal and apply* helpers (applySetNews / applyAddNews / applyUpdateNews / applyDeleteNews / applyEditNews / applyLikeNews) so consumers can plug their own use-case results into a single UI source of truth. applyLikeNews documented as optimistic mutation with manual rollback. - Widgets reference: <app-news-card> input/output contract and the resourceLink pattern (segments differ per owner type), <app-news-form> with onResetForm / onCloseEditMode helpers. - Note that there are no shared HTTP endpoints - each owner type hits its own /<owner>/<id>/news/* surface. - Consumers across project-detail, profile-detail, program-detail, feed. - Known issues: FeedNews living in domain/project/, New naming, triple-copy of news repository ports/use-cases, optimistic applyLikeNews without auto-rollback, fake CDN URLs in static default(). Mark docs/modules/news.md as done in docs/PROJECT.md index. No source changes.
Add docs/modules/feed.md covering the global content feed: - domain/feed/feed-item.model.ts: FeedProject (project preview for feed cards), FeedItemType (vacancy / news / project), FeedItem discriminated union by typeModel with content shapes per type (FeedProject, Vacancy, FeedNews + contentObject ref). - FeedRepositoryPort with single fetchFeed(offset, limit, type) method. Type filter joins values with FILTER_SPLIT_SYMBOL "|". - 3 use-cases: FetchFeedUseCase delegates to repository, ToggleFeedLikeUseCase + ReadFeedNewsUseCase dispatch to the three news repositories (project / profile / program) based on FeedItem.typeModel and contentObject.id - because the backend has no centralized like/read endpoint for feed. - Facades: FeedInfoService (page-scoped, IntersectionObserver for infinite scroll, query param sync, optimistic applyToggleLike), FeedUIInfoService (feedItems$ AsyncState, count, offset, take=10, has-more). - Repository + adapter: thin pass-through for GET /feed/?limit& offset&type with type encoded as pipe-joined string. - Routes: attached inside office shell, no dedicated feed.routes. FeedResolver loads first 10 with the default filter. - Pages: FeedComponent main with @switch by typeModel, NewProjectComponent for project entries (uses IndustryInfoService for industry name), OpenVacancyComponent for vacancy entries, AdvertCardComponent for marketing inserts. News entries reuse <app-news-card>. - Widgets cross-reference: <app-feed-filter>, <app-news-card>. - Consumers: feed is the office shell default landing. - Known issues: like/read dispatch on the frontend instead of a unified backend endpoint, AdvertCardComponent placement algorithm is implicit, FILTER_SPLIT_SYMBOL hardcoded literal, FeedItem flattens project/profile/program news under one typeModel and reconstructs ownership through contentObject.id. Mark docs/modules/feed.md as done in docs/PROJECT.md index. No source changes.
Add docs/modules/chat.md - the most event-heavy module: WS for
realtime + REST for history, with a CQRS-style split into two ports.
- domain/chat: ChatMessage (self-referential replyTo), ChatFile
(extension TODO: mimetype), ChatItem, the full DTO catalogue
(Send/Edit/Delete/Read/Typing for commands, OnChatMessage/
OnEditMessage/OnDeleteMessage/OnReadMessage/TypingInChatEvent/
OnChangeStatus for events) plus ChatEventType enum
(new_message, edit_message, delete_message, message_read,
user_typing, set_online, set_offline).
- Two ports:
- ChatRepositoryPort (REST: loadMessages, loadProjectFiles,
hasUnreads).
- ChatRealtimePort (WS: connect + 5 commands sendMessage/
editMessage/deleteMessage/readMessage/startTyping + 7 event
streams onMessage/onEditMessage/onDeleteMessage/onReadMessage/
onTyping/onSetOnline/onSetOffline). CQRS-style split called
out as the architectural model.
- 16 use-cases tabulated by REST vs WS-command vs WS-event.
- Facades: ChatInfoService + UI for the directs/groups list,
ChatDirectInfoService + UI for the per-chat view (subscribes
to all Observe* use-cases on init), plus the global
ChatStateService (root) holding unread$ + userOnlineStatusCache
used by the header badge and online indicators.
- Legacy ChatDirectService / ChatProjectService noted as still
present alongside the new use-case stack.
- Repositories: ChatRepository (REST pass-through with
plainToInstance), ChatRealtimeRepository (delegates to
ChatWsAdapter wrapping core WebsocketService for
reconnection 5x at environment.websocketReconnectionInterval).
- HTTP endpoints for /messages/*, /messages/files,
/messages/has_unreads/.
- WS adapter: connects to environment.websocketUrl + "/chat/"
with Bearer subprotocol, snake_case <-> camelCase via
WebsocketService, isConnected flag.
- Routes: CHAT_ROUTES (directs/groups + lazy chat-direct),
CHAT_DIRECT_ROUTES (single chatId).
- Pages: ChatComponent (list), ChatCardComponent (preview),
ChatDirectComponent (uses <app-chat-window> + <app-message-input>).
- Resolvers ChatResolver / ChatGroupsResolver / ChatDirectResolver.
- Widget cross-reference: app-chat-window + app-message-input.
- Consumers across project-detail/chat, header badge, online
indicators in info-card/detail, app.component bootstrap.
- Known issues: ChatFile.extension TODO, replyTo unbounded depth,
legacy services beside use-cases, no toast when WS reconnect
exhausts, ChatStateService cache not cleared on logout, chatType
duplicated on every DTO, project query param naming
inconsistency in loadMessages.
Mark docs/modules/chat.md as done in docs/PROJECT.md index.
No source changes.
…vices
Add docs/modules/office-shell.md covering everything around the
feature modules - the application skeleton.
- OfficeComponent shell:
- app-office root with side nav + header + profile-control-panel +
router-outlet, OfficeInfoService bootstraps industries cache,
chat connect + check unreads, online/offline observers, invite
accept/reject from the profile dropdown.
- Page inventory: NavComponent, DeleteConfirmComponent,
ProgramSidebarCardComponent, SnackbarComponent + AnimationService.
- OfficeUIInfoService for invites signal and menu state.
- OfficeResolver loads my invites for the badge.
- Error pages:
- ErrorComponent layout, ErrorNotFoundComponent (static 404),
ErrorCodeComponent (dynamic by :code).
- ERROR_ROUTES with 404 + :code children.
- OFFICE_ROUTES has ** redirect to /error/404 fallback.
- Cross-reference back to ErrorService in core lib.
- Onboarding:
- 4-stage flow (stage-0 base profile + education + workExperience,
stage-1 specializations, stage-2 skills, stage-3 user type).
- ONBOARDING_ROUTES with resolvers on stage-1 and stage-2.
- Per-stage InfoService + UIInfoService facades, plus legacy
OnboardingService still around.
- UI services in ui/services/:
- LoadingService - root, BehaviorSubject<boolean> wired into
<mat-progress-bar> via router events in app.component.
- SnackbarService - subject of Snack {id, text, timeout, type}
with success/error/info methods (no warning).
- NavService - reactive page title via ReplaySubject(1) with
distinctUntilChanged.
- NotificationService - present but unused in current code,
BehaviorSubject<Notification[]> never populated; hasNotifications
semantics are inverted (counts read, not unread).
- OFFICE_ROUTES walkthrough: lazy onboarding + 9 feature lazy
loads + members + profile/edit + profile/:id, plus the 404
fallback. Notes the duplicate /courses and /vacancies entries
(debt: second block is unreachable) and the commented /chats
block.
- Consumers: LoadingService used everywhere via app.component,
SnackbarService for transient feedback, NavService for header
titles, ChatStateService.unread$ for chat badge.
- Known issues: NotificationService inverted hasNotifications +
unused, missing warning() in SnackbarService, duplicate
/courses + /vacancies routes, commented /chats block, legacy
OnboardingService, oversized stage-0 form, OFFICE_ROUTES sprawl.
Mark docs/modules/office-shell.md as done in docs/PROJECT.md index.
Drop projects/social_platform/src/app/ui/pages/office/README.md and
projects/social_platform/src/app/ui/pages/error/README.md - the
descriptions there reference module structures that moved during
the be9344b refactor; superseded by the new doc.
No source changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.