implemented property management - #316
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Sorry @henry-casper, your pull request is larger than the review limit of 150000 diff characters
Reviewer's GuideImplements end-to-end property management capabilities across API, persistence, GraphQL, admin UI, and verification tests, including permissions, soft-delete semantics, and test-time event handler wiring. Sequence diagram for soft-deleted property removal via GraphQLsequenceDiagram
actor AdminUser
participant AdminUI as AdminUI_Properties
participant GraphQL as GraphQL_Server
participant Resolvers as PropertyResolvers
participant Service as PropertyApplicationService
participant Repo as PropertyRepository
participant DB as MongoDB
AdminUser->>AdminUI: click RemoveProperty
AdminUI->>GraphQL: propertyDelete(input.id)
GraphQL->>Resolvers: Mutation.propertyDelete
Resolvers->>Service: requestDelete({ id })
Service->>Repo: getById(id)
Repo->>DB: findById(id).populate(['community','owner'])
Repo-->>Service: Property aggregate
Service-->>Repo: aggregate.requestDelete()
Repo->>DB: save({ isDeleted: true })
Repo-->>Service: deleted aggregate
Service-->>Resolvers: PropertyMutationResult{ status.success }
Resolvers-->>GraphQL: propertyDelete payload
GraphQL-->>AdminUI: success, property removed from list
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Pull request overview
Adds end-to-end property management across the domain, persistence, GraphQL API, community-admin UI, and verification suites.
Changes:
- Adds property CRUD, permissions, role resolution, and soft deletion.
- Adds guarded admin property list/create/detail pages.
- Adds extensive Storybook, acceptance, and E2E coverage plus dependency security overrides.
Reviewed changes
Copilot reviewed 128 out of 129 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
pnpm-workspace.yaml |
Updates security overrides and audit exceptions. |
packages/ocom/ui-community-route-admin/src/section-layout.graphql |
Queries property-management permission. |
packages/ocom/ui-community-route-admin/src/pages/properties.tsx |
Adds property routes. |
packages/ocom/ui-community-route-admin/src/pages/properties.stories.tsx |
Tests guarded property page states. |
packages/ocom/ui-community-route-admin/src/pages/properties-list.tsx |
Adds property-list page layout. |
packages/ocom/ui-community-route-admin/src/pages/properties-list.stories.tsx |
Covers list page states. |
packages/ocom/ui-community-route-admin/src/pages/properties-detail.tsx |
Adds property-detail page. |
packages/ocom/ui-community-route-admin/src/pages/properties-detail.stories.tsx |
Covers detail page states. |
packages/ocom/ui-community-route-admin/src/pages/properties-create.tsx |
Adds property-create page. |
packages/ocom/ui-community-route-admin/src/pages/properties-create.stories.tsx |
Covers create page rendering. |
packages/ocom/ui-community-route-admin/src/index.tsx |
Registers property menu and route. |
packages/ocom/ui-community-route-admin/src/components/properties-route-guard.container.tsx |
Enforces route permission. |
packages/ocom/ui-community-route-admin/src/components/properties-route-guard.container.stories.tsx |
Covers guard outcomes. |
packages/ocom/ui-community-route-admin/src/components/properties-list.tsx |
Renders the property table. |
packages/ocom/ui-community-route-admin/src/components/properties-list.stories.tsx |
Covers property-table states. |
packages/ocom/ui-community-route-admin/src/components/properties-list.container.tsx |
Loads and navigates properties. |
packages/ocom/ui-community-route-admin/src/components/properties-list.container.stories.tsx |
Covers list-container behavior. |
packages/ocom/ui-community-route-admin/src/components/properties-list.container.graphql |
Defines property-list query. |
packages/ocom/ui-community-route-admin/src/components/properties-detail.tsx |
Adds edit and removal form. |
packages/ocom/ui-community-route-admin/src/components/properties-detail.stories.tsx |
Covers detail interactions. |
packages/ocom/ui-community-route-admin/src/components/properties-detail.container.tsx |
Handles update and deletion. |
packages/ocom/ui-community-route-admin/src/components/properties-detail.container.stories.tsx |
Covers detail-container flows. |
packages/ocom/ui-community-route-admin/src/components/properties-detail.container.graphql |
Defines detail CRUD operations. |
packages/ocom/ui-community-route-admin/src/components/properties-create.tsx |
Adds property creation form. |
packages/ocom/ui-community-route-admin/src/components/properties-create.stories.tsx |
Covers create-form validation. |
packages/ocom/ui-community-route-admin/src/components/properties-create.container.tsx |
Handles property creation. |
packages/ocom/ui-community-route-admin/src/components/properties-create.container.stories.tsx |
Covers creation outcomes. |
packages/ocom/ui-community-route-admin/src/components/properties-create.container.graphql |
Defines create mutation. |
packages/ocom/persistence/src/datasources/readonly/property/property/property.read-repository.ts |
Adds filtered property reads. |
packages/ocom/persistence/src/datasources/readonly/property/property/property.read-repository.test.ts |
Tests read filtering and population. |
packages/ocom/persistence/src/datasources/readonly/property/property/property.data.ts |
Defines property data source. |
packages/ocom/persistence/src/datasources/readonly/property/property/index.ts |
Exposes property repository. |
packages/ocom/persistence/src/datasources/readonly/property/index.ts |
Builds property read context. |
packages/ocom/persistence/src/datasources/readonly/index.ts |
Registers property read context. |
packages/ocom/persistence/src/datasources/domain/property/property/property.repository.ts |
Adds population and soft-delete saving. |
packages/ocom/persistence/src/datasources/domain/property/property/property.repository.soft-delete.test.ts |
Tests soft-delete persistence. |
packages/ocom/graphql/src/schema/types/property.resolvers.ts |
Adds property query and mutation resolvers. |
packages/ocom/graphql/src/schema/types/property.graphql |
Defines property GraphQL API. |
packages/ocom/graphql/src/schema/types/member.resolvers.ts |
Adds role lookup fallback. |
packages/ocom/graphql/src/schema/types/member.resolvers.additional.test.ts |
Updates role resolver coverage. |
packages/ocom/graphql/src/schema/types/end-user-role.graphql |
Exposes property permissions. |
packages/ocom/domain/src/domain/contexts/property/property/index.ts |
Exports property domain types. |
packages/ocom/data-sources-mongoose-models/src/models/property/property.model.ts |
Adds deletion flag and location changes. |
packages/ocom/application-services/src/index.ts |
Registers property services. |
packages/ocom/application-services/src/contexts/property/property/update.ts |
Implements property updates. |
packages/ocom/application-services/src/contexts/property/property/request-delete.ts |
Implements deletion requests. |
packages/ocom/application-services/src/contexts/property/property/query-by-id.ts |
Adds property lookup. |
packages/ocom/application-services/src/contexts/property/property/query-by-community-id.ts |
Adds community property lookup. |
packages/ocom/application-services/src/contexts/property/property/index.ts |
Composes property operations. |
packages/ocom/application-services/src/contexts/property/property/create.ts |
Implements property creation. |
packages/ocom/application-services/src/contexts/property/index.ts |
Builds property service context. |
packages/ocom/application-services/src/contexts/community/member/query-by-id-with-role.ts |
Adds populated member lookup. |
packages/ocom/application-services/src/contexts/community/member/index.ts |
Registers member-role lookup. |
packages/ocom-verification/verification-shared/src/scenarios/property/property-management.feature |
Specifies property CRUD behavior. |
packages/ocom-verification/verification-shared/src/scenarios/property/property-authorization.feature |
Specifies authorization behavior. |
packages/ocom-verification/verification-shared/src/pages/property-form.page.ts |
Adds shared property-form page object. |
packages/ocom-verification/verification-shared/src/pages/properties-list.page.ts |
Adds shared property-list page object. |
packages/ocom-verification/verification-shared/src/pages/index.ts |
Exports property page objects. |
packages/ocom-verification/e2e-tests/src/step-definitions/index.ts |
Registers property E2E steps. |
packages/ocom-verification/e2e-tests/src/shared/support/graphql-response.ts |
Adds GraphQL response helpers. |
packages/ocom-verification/e2e-tests/src/contexts/property/tasks/view-property-details.ts |
Adds detail-view task. |
packages/ocom-verification/e2e-tests/src/contexts/property/tasks/view-properties-list.ts |
Adds list-view task. |
packages/ocom-verification/e2e-tests/src/contexts/property/tasks/update-property.ts |
Adds update task. |
packages/ocom-verification/e2e-tests/src/contexts/property/tasks/ensure-property-exists.ts |
Adds conditional creation task. |
packages/ocom-verification/e2e-tests/src/contexts/property/tasks/delete-property.ts |
Adds removal task. |
packages/ocom-verification/e2e-tests/src/contexts/property/tasks/create-property.ts |
Adds creation task. |
packages/ocom-verification/e2e-tests/src/contexts/property/tasks/become-property-manager.ts |
Provisions E2E property managers. |
packages/ocom-verification/e2e-tests/src/contexts/property/step-definitions/index.ts |
Loads property steps. |
packages/ocom-verification/e2e-tests/src/contexts/property/questions/property-screen.ts |
Adds property-screen assertions. |
packages/ocom-verification/e2e-tests/src/contexts/property/notes/property-notes.ts |
Defines E2E property state. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/submit-property-save.ts |
Captures update outcomes. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/submit-property-create.ts |
Captures creation outcomes. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/record-property-notes.ts |
Records list baselines. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/open-property-detail.ts |
Opens property details. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/open-properties-list.ts |
Opens property lists. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/open-create-property-form.ts |
Opens creation form. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/open-admin-portal.ts |
Opens provisioned admin portal. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/fill-property-form.ts |
Fills property forms. |
packages/ocom-verification/e2e-tests/src/contexts/property/interactions/confirm-property-removal.ts |
Confirms property deletion. |
packages/ocom-verification/e2e-tests/src/contexts/property/abilities/admin-portal-page.ts |
Adds property navigation helpers. |
packages/ocom-verification/acceptance-ui/tsconfig.json |
Includes admin route sources. |
packages/ocom-verification/acceptance-ui/src/step-definitions/index.ts |
Registers property UI steps. |
packages/ocom-verification/acceptance-ui/src/contexts/property/tasks/properties-screen.ts |
Renders property acceptance screens. |
packages/ocom-verification/acceptance-ui/src/contexts/property/tasks/manage-property.ts |
Implements UI CRUD tasks. |
packages/ocom-verification/acceptance-ui/src/contexts/property/step-definitions/index.ts |
Loads property UI steps. |
packages/ocom-verification/acceptance-ui/src/contexts/property/questions/property-screen.ts |
Adds UI screen assertions. |
packages/ocom-verification/acceptance-ui/src/contexts/property/questions/property-outcome.ts |
Adds mocked outcome questions. |
packages/ocom-verification/acceptance-ui/src/contexts/property/notes/property-ui-notes.ts |
Defines UI scenario state. |
packages/ocom-verification/acceptance-api/src/world.ts |
Registers property API abilities. |
packages/ocom-verification/acceptance-api/src/step-definitions/index.ts |
Registers property API steps. |
packages/ocom-verification/acceptance-api/src/shared/graphql/property-operations.ts |
Defines verification GraphQL operations. |
packages/ocom-verification/acceptance-api/src/shared/abilities/update-property.ts |
Adds update ability. |
packages/ocom-verification/acceptance-api/src/shared/abilities/provision-resident-member.ts |
Provisions unauthorized residents. |
packages/ocom-verification/acceptance-api/src/shared/abilities/index.ts |
Exports property abilities. |
packages/ocom-verification/acceptance-api/src/shared/abilities/graphql-client.ts |
Adds principal context headers. |
packages/ocom-verification/acceptance-api/src/shared/abilities/delete-property.ts |
Adds deletion ability. |
packages/ocom-verification/acceptance-api/src/shared/abilities/create-property.ts |
Adds creation ability. |
packages/ocom-verification/acceptance-api/src/shared/abilities/actor-auth.ts |
Tracks end-user tokens and context. |
packages/ocom-verification/acceptance-api/src/servers/api-graphql-test-server.ts |
Passes test principal context. |
packages/ocom-verification/acceptance-api/src/mock-application-services.ts |
Registers handlers and end-user validation. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/view-property-details.ts |
Adds API detail-view task. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/view-properties-list.ts |
Adds API list-view task. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/update-property.ts |
Adds API update task. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/update-property-input.ts |
Maps update inputs. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/provision-resident-member.ts |
Arranges resident actors. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/delete-property.ts |
Adds API deletion task. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/create-property.ts |
Adds API creation task. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/become-property-manager.ts |
Arranges property managers. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/attempt-update-property.ts |
Captures rejected updates. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/attempt-delete-property.ts |
Captures rejected deletions. |
packages/ocom-verification/acceptance-api/src/contexts/property/tasks/attempt-create-property.ts |
Captures rejected creations. |
packages/ocom-verification/acceptance-api/src/contexts/property/step-definitions/index.ts |
Loads property API steps. |
packages/ocom-verification/acceptance-api/src/contexts/property/questions/viewed-property.ts |
Reads viewed property data. |
packages/ocom-verification/acceptance-api/src/contexts/property/questions/property-retrievable.ts |
Checks post-deletion retrieval. |
packages/ocom-verification/acceptance-api/src/contexts/property/questions/property-operation-outcome.ts |
Reads operation outcomes. |
packages/ocom-verification/acceptance-api/src/contexts/property/questions/property-named.ts |
Finds properties by name. |
packages/ocom-verification/acceptance-api/src/contexts/property/questions/property-manager-permission.ts |
Verifies role permission. |
packages/ocom-verification/acceptance-api/src/contexts/property/questions/property-field.ts |
Reads property fields. |
packages/ocom-verification/acceptance-api/src/contexts/property/questions/properties-list.ts |
Queries community properties. |
packages/ocom-verification/acceptance-api/src/contexts/property/notes/property-notes.ts |
Defines API scenario state. |
packages/ocom-verification/acceptance-api/package.json |
Adds verification dependencies. |
codegen.yml |
Maps GraphQL Property to domain type. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…scade npm latest (4.13.2, also 4.13.1) point at CDN artifacts that 404 (Azure.Functions.Cli.linux-x64.<version>.zip missing), breaking the unpinned global install. 4.13.0 is the newest release with a working artifact (verified via ranged GET -> HTTP 206). Also add succeeded() to the func-tools/Playwright install conditions and replace always() on the Playwright verify step, so a failed install no longer cascades into misleading 'pnpm: command not found' errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…unique name index to active properties
- getById now treats soft-deleted properties as not found, preventing
update/delete mutations against hidden records (PR review P1)
- getAll filters out soft-deleted documents
- unique {community, propertyName} index is now partial on
{isDeleted: false} so deleted property names can be reused (PR review P2)
- added compensating {community, isDeleted} index for listing queries
- covered by repository unit tests, index contract tests, and two new
acceptance-api scenarios
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tibility
Reverts the partial {isDeleted: false} unique index and the compensating
{community, isDeleted} index so the PR requires no manual index migration
on deployed databases (createIndex with changed options would conflict
with the existing index). Deleted property names remain reserved.
Keeps the P1 fix: soft-deleted properties are still excluded from the
write repository (getById/getAll), so they cannot be mutated.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Scope property reads to community members: property/propertiesByCommunityId now verify the actor's membership in the target community (Unauthorized otherwise) - Require canManageProperties for admin property updates via a public assertCanManageProperties guard on the Property aggregate - Forward explicit nulls for bedrooms/bathrooms/squareFeet so numeric listing details can be cleared end to end (UI container, resolver, command) - Evict deleted properties from the Apollo cache after propertyDelete - Resolve Property.owner through the member read model so nested account fields are GraphQL-safe - Pin func-tools CI cache to exact version key; inexact hits no longer skip installation of the pinned Core Tools version - Drain in-flight integration event handlers before per-scenario DB reset and skip the mock server dev seed under tests (SKIP_DEV_SEED) to stop acceptance cross-scenario contamination - Note: member navigation finding was a false positive (MemberReadRepo.isAdmin already includes canManageProperties) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The spec mandates all admin-side property queries enforce propertyPermissions.canManageProperties. The previous fix only verified community membership, letting residents without the permission read the property directory. Reads now load the acting member's role and require canManageProperties in the target community; the contradictory resident-can-view scenario is replaced with rejection scenarios for both list and details. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ry application services Property read authorization now lives in the application services and is bound to the request's current member/community context: - Expose the request-scoped passport on DataSources so application services can evaluate domain visas on read operations. - Guard Property queryById/queryByCommunityId with the property visa (canManageProperties or system account). The member passport is built from the request's x-member-id/x-community-id hints and the MemberPropertyVisa denies cross-community roots, so a manager acting under a different community context is rejected even if they hold manage permissions elsewhere. - Drop the resolver-level membership lookup that authorized via any membership matching the requested community; resolvers now only require a verified user and delegate authorization to the services. - New acceptance scenarios: a manager who switches communities can no longer view their original community's list or property details. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ults queryByCommunityId previously authorized only returned rows, so an unauthorized actor querying a community with no properties received an empty list instead of Unauthorized. The query now evaluates the property visa against a community-scoped root before reading (property visas scope by the root's community, so the same manage/system predicate applies), keeping the per-row check as defense-in-depth. New red-first coverage: unit tests assert the read repo is never called on denial and empty communities still reject; acceptance scenario covers a resident querying an empty community. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Deny property access for deactivated members: MemberPropertyVisa now requires the acting user's member account to be ACCEPTED (rejected or pending accounts are refused), covering reads and writes through the passport choke point. New domain visa scenarios plus acceptance scenarios with a provisioned deactivated property manager. - Omit an empty propertyType from property updates in the admin detail container: newly created properties have no type, and the domain rejects '' — name/numeric-only edits no longer fail. - Make delete cache handling truthful: evict and refetch only after the server confirms deletion, and stop awaiting the list refetch so a refetch failure cannot make a successful removal look failed. - Resolve Property.owner through the readonly member read model (queryByIdWithRole) instead of the transactional unit of work, removing a MongoDB transaction per property row. - Align property name maxLength (100) in create/detail forms with the domain and schema limit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Property.owner resolver still issued one readonly member query per property row. Batch all concurrent owner resolutions of a request into a single query: - MemberReadRepo.getByIdsWithRole: fetch members for a set of ids with role populated via one $in find (no query when the set is empty). - Member application service exposes queryByIdsWithRole. - Property.owner resolves through a per-request DataLoader keyed by the request-scoped ApplicationServices instance, so batches and cached members never cross request/passport boundaries. Resolver tests assert concurrent lookups coalesce into one batched call, missing owners resolve to null, and loaders are request-isolated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… active-account gate Address third-party review findings: - Zero-valued listing fields become null (P2): the property domain adapter used `|| null` on numeric getters, so legal 0 values for price, rentHigh, rentLow, lease, maxGuests, bedrooms, bathrooms, squareFeet, yearBuilt, and lotSize were corrupted to null on read. Getters now use `?? null`. - Clearing property type reported success without persisting (P2): an explicit null propertyType now flows end-to-end. The domain aggregate accepts null as a deliberate clear (still visa-guarded), the mongoose model/adapter persist and surface null, the update application service and GraphQL resolver forward explicit null instead of dropping it, and the admin detail form submits null when the field is cleared. New acceptance scenario covers the round trip. - Deactivated members passed frontend authorization (P3): the admin section-layout query now selects member account statuses and the current end user id, and both the Properties nav gate and the route guard additionally require an ACCEPTED account for the current user, mirroring the backend visa. Deep links and nav now deny deactivated or pending members up front. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…o reads Review fixes (ninth review, both confirmed real): - Member.role resolver: the fallback lookup accessed memberWithRole.role outside any catch, so a missing/dangling role reference surfaced as a GraphQL error instead of the nullable role: null. The fallback access is now guarded and returns null. - PropertyRepository.getById/getAll: reads were not bound to the unit-of- work session, so they escaped the transaction snapshot and could race concurrent saves/soft-deletes. Reads now join the transaction via .session(this.session), enabling MongoDB write-conflict detection with the unit of work's retry (fresh repository per attempt re-reads and observes isDeleted). Tests (red first): dangling-role resolver test in member.resolvers.additional.test.ts; session-binding scenarios in property.repository.feature/test with session spies on the query chain. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Properties list adds price, formatted display address, and owner columns - Create/detail pages expose all business fields in Overview/Location/Listing (Details, Amenities, Media, Agent) sections via shared PropertyForm - Create accepts all fields at once and returns to the properties list - Bathrooms restricted to 0.5 increments in domain VO, API, and UI validation - GraphQL exposes canonical address fields, full listing detail, and owner assignment with same-community validation; null-clear semantics preserved - Detail page titled "Property Details"; Storybook coverage for all changes - Serenity property-fields scenarios implemented across acceptance-api, acceptance-ui, and e2e suites Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 185 out of 186 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (3)
packages/ocom/graphql/src/schema/types/property.resolvers.ts:218
- An explicit
nullfortagsis currently ignored, but the new form sendstags: nullwhen the field is cleared. Updating a property after removing all tags therefore leaves the old tags persisted. Convertnullto an empty array while preservingundefinedas “unchanged.”
packages/ocom/ui-community-route-admin/src/components/properties-create.container.tsx:25 - The mutation loading state is discarded, so the Create Property button remains enabled while a request is in flight. A double click can submit two create mutations and produce duplicate/error feedback. Pass the mutation's loading state through
PropertiesCreatetoPropertyForm.submittingso the button displays loading and blocks repeat submission.
packages/ocom/ui-community-route-admin/src/components/format-display-address.ts:29 countryis accepted and queried for list rows but is never included in the formatted address. International addresses can therefore render identically despite different countries, and a country-only address incorrectly renders asN/A. Include the trimmed country as the final address part and update the tests accordingly.
| listedForRent: { type: Boolean, required: false, default: false }, | ||
| listedForLease: { type: Boolean, required: false, default: false }, | ||
| listedInDirectory: { type: Boolean, required: false, default: false }, | ||
| isDeleted: { type: Boolean, required: false, default: false }, |
Summary by Sourcery
Add full-stack property management support for end users, from GraphQL schema and application services through persistence soft-deletes to community admin UI pages, with role-based permissions and extensive verification across API, UI, and E2E tests.
New Features:
Bug Fixes:
Enhancements:
Build:
Documentation:
Tests:
Chores: