-
Notifications
You must be signed in to change notification settings - Fork 0
implemented property management #316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
henry-casper
wants to merge
29
commits into
main
Choose a base branch
from
feat/Implement-property-management-section-on-admin-side-of-Community-Portal
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
4f4890b
implemented property management
henry-casper 1fc4696
fix(ci): pin azure-functions-core-tools to 4.13.0 and stop failure ca…
henry-casper e77606a
fix: exclude soft-deleted properties from write repository and scope …
henry-casper ea31333
revert: restore full unique property name index for deployed DB compa…
henry-casper 493ddd4
fix: address second review findings for property management
henry-casper ec8038b
fix: property reads require canManageProperties, not mere membership
henry-casper dcd4e1b
fix(property): enforce hint-scoped visa authorization in property que…
henry-casper ece9882
fix(property): authorize community property reads before fetching res…
henry-casper 46592cb
fix(property): address sixth review findings
henry-casper e8eb3c6
perf(property): batch owner lookups to eliminate N+1 queries
henry-casper 4a55eae
fix(property): preserve zero listing values, clearable type, frontend…
henry-casper 809ca83
fix: return null for dangling member roles; session-bind property rep…
henry-casper 0b9ea3f
feat(property): full-field admin property management per UI changes spec
henry-casper 62eb0d8
fix(property): address property management review findings
henry-casper 469e6c2
fix(property): address second-round review findings
henry-casper fe47f13
fix(property): fail closed on mismatched principal hints, cap tags an…
henry-casper 41e6256
fix(property): reject >50 tags server-side, narrow passport fallback,…
henry-casper 7a843ab
fix(property): decouple mutation status from post-commit reads, harde…
henry-casper cb71fbc
Fix round-6 review findings: assign-role gate, oracle, soft-delete, n…
henry-casper 069ee7e
Fix round-7 review findings and NodeNext JSON build failure
henry-casper 2e6ec69
Order UI app builds before acceptance-ui suites in the task graph
henry-casper 601d000
fix(property): round-9 review fixes — section gating, nav access, lea…
henry-casper 6ab106f
fix: exclude countries data from Sonar CPD, authorize owner options, …
henry-casper e3aa4ea
fix: minimize owner-option payload, guard admin-only routes, fix filt…
henry-casper eeba099
fix: project Property.owner to the minimal PropertyOwnerOption type
henry-casper ddc6fdf
fix: gate staff role permission grants by caller enterprise app role …
henry-casper 9dfd2ab
fix: enforce staff tier and property authorization inside transactions
henry-casper 0d83b4f
fix: address property management review feedback
henry-casper 05545b2
chore: merge main into feat/Implement-property-management-section-on-…
henry-casper File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
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
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
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
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
26 changes: 26 additions & 0 deletions
26
packages/ocom-verification/acceptance-api/src/contexts/property/notes/property-notes.ts
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /** Input details used when updating a property through the API. */ | ||
| export interface PropertyUpdateDetails { | ||
| propertyName?: string | undefined; | ||
| propertyType?: string | null | undefined; | ||
| tags?: string[] | undefined; | ||
| bedrooms?: number | null | undefined; | ||
| bathrooms?: number | null | undefined; | ||
| squareFeet?: number | null | undefined; | ||
| } | ||
|
|
||
| /** Scenario-local property state shared between tasks and questions via actor notes. */ | ||
| export interface PropertyNotes { | ||
| activeCommunityId: string; | ||
| activeCommunityName: string; | ||
| actingMemberId: string; | ||
| lastPropertyStatus: string; | ||
| lastPropertyId: string; | ||
| lastPropertyName: string; | ||
| lastPropertyError: string; | ||
| listedPropertyNames: string[]; | ||
| viewedPropertyId: string; | ||
| viewedPropertyName: string; | ||
| previousCommunityId: string; | ||
| previousMemberId: string; | ||
| submittedPropertyFields: Record<string, string>; | ||
| } |
41 changes: 41 additions & 0 deletions
41
packages/ocom-verification/acceptance-api/src/contexts/property/questions/properties-list.ts
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import { GraphQLClient } from '@cellix/serenity-framework/clients/graphql'; | ||
| import { type Actor, type AnswersQuestions, notes, Question, type UsesAbilities } from '@serenity-js/core'; | ||
| import { PROPERTIES_BY_COMMUNITY_ID_QUERY, type PropertyResult } from '../../../shared/graphql/property-operations.ts'; | ||
| import type { PropertyNotes } from '../notes/property-notes.ts'; | ||
|
|
||
| /** | ||
| * Question that reads the non-deleted properties of a community from the API. | ||
| * Defaults to the actor's active community recorded in notes. | ||
| */ | ||
| export class PropertiesList extends Question<Promise<PropertyResult[]>> { | ||
| static displayed(): PropertiesList { | ||
| return new PropertiesList(undefined); | ||
| } | ||
|
|
||
| static ofCommunity(communityId: string): PropertiesList { | ||
| return new PropertiesList(communityId); | ||
| } | ||
|
|
||
| private constructor(private readonly communityId: string | undefined) { | ||
| super('the properties list'); | ||
| } | ||
|
|
||
| override async answeredBy(actor: AnswersQuestions & UsesAbilities): Promise<PropertyResult[]> { | ||
| const communityId = this.communityId ?? (await this.readActiveCommunityId(actor)); | ||
| if (!communityId) { | ||
| throw new Error('No community id available to list properties. Did the actor become a property manager or member of a community first?'); | ||
| } | ||
| const response = await GraphQLClient.as(actor as unknown as Actor).execute(PROPERTIES_BY_COMMUNITY_ID_QUERY, { communityId }); | ||
| return response.data['propertiesByCommunityId'] as PropertyResult[]; | ||
| } | ||
|
|
||
| override toString = () => 'the properties list'; | ||
|
|
||
| private async readActiveCommunityId(actor: AnswersQuestions & UsesAbilities): Promise<string | undefined> { | ||
| try { | ||
| return await actor.answer(notes<PropertyNotes>().get('activeCommunityId')); | ||
| } catch { | ||
| return undefined; | ||
| } | ||
| } | ||
| } |
56 changes: 56 additions & 0 deletions
56
packages/ocom-verification/acceptance-api/src/contexts/property/questions/property-field.ts
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { type AnswersQuestions, Question, type UsesAbilities } from '@serenity-js/core'; | ||
| import type { PropertyResult } from '../../../shared/graphql/property-operations.ts'; | ||
| import { PropertyNamed } from './property-named.ts'; | ||
|
|
||
| type ScalarField = 'propertyType'; | ||
| type ListingDetailField = 'bedrooms' | 'bathrooms' | 'squareFeet'; | ||
|
|
||
| /** | ||
| * Question that reads a single field of a named property live from the API. | ||
| * Fails with a diagnostic error when the property cannot be found. | ||
| */ | ||
| export class PropertyField extends Question<Promise<string | number | null>> { | ||
| static propertyType(propertyName: string): PropertyField { | ||
| return new PropertyField(propertyName, 'propertyType', undefined); | ||
| } | ||
|
|
||
| static bedrooms(propertyName: string): PropertyField { | ||
| return new PropertyField(propertyName, undefined, 'bedrooms'); | ||
| } | ||
|
|
||
| static bathrooms(propertyName: string): PropertyField { | ||
| return new PropertyField(propertyName, undefined, 'bathrooms'); | ||
| } | ||
|
|
||
| static squareFeet(propertyName: string): PropertyField { | ||
| return new PropertyField(propertyName, undefined, 'squareFeet'); | ||
| } | ||
|
|
||
| private constructor( | ||
| private readonly propertyName: string, | ||
| private readonly scalarField: ScalarField | undefined, | ||
| private readonly listingDetailField: ListingDetailField | undefined, | ||
| ) { | ||
| super(`the ${scalarField ?? listingDetailField} of the property "${propertyName}"`); | ||
| } | ||
|
|
||
| override async answeredBy(actor: AnswersQuestions & UsesAbilities): Promise<string | number | null> { | ||
| const property = await actor.answer(PropertyNamed.called(this.propertyName)); | ||
| if (!property) { | ||
| throw new Error(`Property "${this.propertyName}" was not found in the properties list`); | ||
| } | ||
| return this.fieldOf(property); | ||
| } | ||
|
|
||
| override toString = () => `the ${this.scalarField ?? this.listingDetailField} of the property "${this.propertyName}"`; | ||
|
|
||
| private fieldOf(property: PropertyResult): string | number | null { | ||
| if (this.scalarField) { | ||
| return property[this.scalarField]; | ||
| } | ||
| if (this.listingDetailField) { | ||
| return property.listingDetail?.[this.listingDetailField] ?? null; | ||
| } | ||
| throw new Error('PropertyField was constructed without a field'); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.