Skip to content

feat(projects): add star, unstar and get_starred for starred projects - #801

Open
prasad-albert wants to merge 9 commits into
mainfrom
cakeagents/ai-2153
Open

prasad-albert wants to merge 9 commits into
mainfrom
cakeagents/ai-2153

Conversation

@prasad-albert

@prasad-albert prasad-albert commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

What

client.projects can now star (pin) a project for the current user, remove the star, and list the user's starred projects as fully populated Projects. It's the same "Starred Projects" feature the web app has.

client.projects.star(id="PRO1289")            # -> Project
for p in client.projects.get_starred():       # -> Iterator[Project]
    print(p.id, p.description)
client.projects.unstar(id="PRO1289")          # -> None

Why

Ask Albert couldn't pin projects for users (AI-2153). It even claimed starring was a browser-only preference. In fact stars are stored server-side by api-personalization, and the SDK simply had no wrapper for it. Ask Albert generates its tools from SDK methods, so this change is what unblocks that request.

How

  • Backend: api-personalization at /api/v3/personalization, category "Starred Projects".
    • Star: POST [{category, savedId: PRO…, savedName}].
    • List: GET ?createdBy=<me>&category=Starred Projects, key-based pagination.
    • Unstar: DELETE /personalization/{USP id}.
  • A new PersonalizationCollection (client.personalization) wraps /api/v3/personalization with basic CRUD: create, get_by_id, get_all (category/sub_category/saved_id/user_id filters, current user by default), delete. This unlocks the other personalization categories (Hidden Rows, Saved Filters, User Configuration, Notification, Skills) for future work. PATCH is intentionally deferred: its ops are category-specific and require exact old-value matching.
  • The star / unstar / get_starred methods live on ProjectCollection and delegate to PersonalizationCollection. There's no separate starred-project model: every method returns Project.
  • star fetches the project first, which checks that it exists and supplies savedName. It returns that project.
    • Starring an already-starred project is idempotent. The API's 400 savedId already exist is treated as success, and any other 400 is still raised.
  • unstar finds the user's starred record(s) whose savedId matches and deletes them. If the project isn't starred, nothing happens.
  • get_starred wraps the key-mode paginator in a MappedPaginator that hydrates each item with get_by_id, the same pattern as users.get_all.
    • Projects the user can no longer read are logged and skipped.
    • It sends limit=200 (the API's maximum) explicitly. The handler calls parseInt(params.limit) with no fallback, so I didn't want to rely on the OpenAPI default of 100 being applied.
  • Stars always belong to the authenticated user; the API derives parentId from the token. So a service-credential client stars for the service user.
  • The change is additive only, with no backward-compatibility impact.

Testing

  • uv run pytest tests/unit: 1249 passed. That includes new unit tests for the personalization query builder, record matching, albertId/id alias round-trips, and detecting the duplicate-star error, plus the meta tests for keyword-only arguments, max_items, docstrings and the Methods listing.
  • New integration test test_star_get_starred_and_unstar_project in tests/integration/collections/test_projects.py. It covers star, idempotent re-star, get_starred, unstar, and unstar on a project that isn't starred.
  • New integration test tests/integration/collections/test_personalization.py covering create, get_by_id, get_all (by category and by saved_id), and delete.
    • Not run in the authoring environment because it has no ALBERT_* credentials. Please run: uv run pytest tests/integration/collections/test_projects.py tests/integration/collections/test_personalization.py -v -n 4
  • The POST contract was confirmed against a live call supplied by the reviewer. The response is [{"id":"USP17620","parentId":"USR4227","savedId":"PROMO130903","savedName":"test-worksheets"}].

Linear: AI-2153
Cake session: https://agents.ai.albertinventdev.com/sessions/875eb734-655e-4d08-9489-12bba899becf

Lets callers (including Ask Albert) pin projects for the current user, matching
the web app's Starred Projects. get_starred yields fully populated Projects and
unstar on a project that is not starred is a no-op. Refs AI-2153.
@claude

claude Bot commented Sep 28, 2026

Copy link
Copy Markdown

Code Review

Issues Found

  • [src/albert/collections/projects.py:445-447] _starred_record_ids reads the record ID only from albertId, but the personalization service returns it under id. The PR body confirms the live shape is [{"id":"USP17620","parentId":...,"savedId":...}] (the POST response), and the GET list is the same service. If the list also returns id, _starred_record_ids returns [] and unstar silently deletes nothing (a data-correctness bug the integration test would catch, but that test was not run: no credentials). The rest of the codebase defends against this (pagination.py:190, property_data.py:262 use albertId or id). Use record.get("albertId") or record.get("id") for both the guard and the value.
  • [src/albert/collections/projects.py:387] get_starred is missing @validate_call. Every sibling list/search method in this collection (search, document_search, get_all) declares it; add it for consistency and max_items coercion.

Verify against live API

  • [src/albert/collections/projects.py:432] The KEY-mode paginator relies on the default _response_items (reads Items/items). api-personalization is a separate service from the users list endpoint; if its GET wraps items under a different key (or returns a bare list), iteration stops immediately and get_starred/unstar return nothing. Confirm the GET list response key when running the integration test.

Summary

2 issues found, plus one contract to verify. The albertId vs id mismatch is the significant one: given the confirmed id-keyed response, unstar likely no-ops silently against the live API.

…ed args

Address review on #801: fall back to the id key when matching starred records
and add @validate_call to get_starred for consistency with sibling methods.
@claude

claude Bot commented Sep 28, 2026

Copy link
Copy Markdown

Code Review

Issues Found

  • [src/albert/collections/projects.py:426-437] _starred_records builds a plain AlbertPaginator in KEY mode with no _response_items override, so pagination reads items from data["Items"]/data["items"] and the continuation cursor from data["lastKey"]. The only confirmed personalization contract in this PR is the POST response, which is a bare JSON array ([{"id":"USP17620",...}]), not an {Items, lastKey} wrapper. If the GET list response is also a bare array (or wraps items under a different key), get_starred/unstar silently yield nothing, and _record_total(data) calls data.get("total") on a list, raising AttributeError. Per OPINIONS.md ("override _response_items for non-standard response keys"), the GET shape needs confirmation. The integration test that would exercise this path was not run in the authoring environment.

Summary

1 issue found. Correctness of star/get_starred/unstar hinges on the personalization GET response matching the standard {Items, lastKey} pagination shape, which is unverified. Please run uv run pytest tests/integration/collections/test_projects.py -v before merge and add an _response_items override if the endpoint uses a non-standard key. The rest (keyword-only args, @validate_call, docstrings, modern type hints, idempotent-star handling, case-insensitive record matching) looks correct.

@claude

claude Bot commented Sep 29, 2026

Copy link
Copy Markdown

Code Review

Issues Found

  • [src/albert/collections/projects.py:426] _starred_records uses a plain AlbertPaginator (KEY mode) against the new /api/v3/personalization endpoint. AlbertPaginator._response_items only reads data["Items"]/data["items"]. api-personalization is a separate service and its GET list envelope is not confirmed in the PR (only the POST response shape was verified against a live call). If it returns records under any other key (e.g. data, results, or a bare list), every page reads as empty and get_starred/unstar silently return nothing while stars exist. Per OPINIONS ("override _response_items for non-standard response keys"), this must be confirmed. The integration test that would catch it was not run in the authoring environment; please run uv run pytest tests/integration/collections/test_projects.py::test_star_get_starred_and_unstar_project -v before merge, or override _response_items if the key differs.

Summary

1 issue found. Contingent correctness risk: the feature works only if the personalization GET envelope uses the standard Items key, which is currently unverified since integration tests were not run. Everything else (keyword-only args, @validate_call, specific BadRequestError/NotFoundError handling, modern type hints, docstrings, Methods listing, conventional feat title) is correct.

…ion model

Covers create, get_by_id, get_all (category/sub_category/saved_id/user_id
filters, current user by default), and delete over /api/v3/personalization.
PATCH is intentionally deferred: its ops are category-specific and require
exact old-value matching. Refs AI-2153.
…onCollection

Same public API and wire behavior; the one-off personalization calls in
ProjectCollection now go through client.personalization. Refs AI-2153.
@claude

claude Bot commented Sep 30, 2026

Copy link
Copy Markdown

Looks good - no bugs or correctness issues found.

@lkubie

lkubie commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

CircleCI Integration Tests failed

Branch: cakeagents/ai-2153 (dad2074)
Build: https://circleci.com/gh/albert-labs/albert-python/8744

=========================== short test summary info ============================
FAILED tests/integration/collections/test_personalization.py::test_personalization_crud@projects - pydantic_core._pydantic_core.ValidationError: 1 validation error for Personalization
category
  Field required [type=missing, input_value={'id': 'USP1323', 'parent...Personalization Target'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.13/v/missing
FAILED tests/integration/collections/test_projects.py::test_star_get_starred_and_unstar_project@projects - pydantic_core._pydantic_core.ValidationError: 1 validation error for Personalization
category
  Field required [type=missing, input_value={'id': 'USP1324', 'parent...73e2 - Project to Star'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.13/v/missing
SKIPPED [10] tests/integration/collections/test_cas.py: CAS collection is deprecated in favor of Substance v4; the testing tenant has migrated to substance_v4.
SKIPPED [1] tests/integration/collections/test_data_templates.py:193: No eligible user returned by users.search() for ACL update.
SKIPPED [1] tests/integration/collections/test_inventory.py:210: LLM search is currently not working as expected.
SKIPPED [1] tests/integration/collections/test_data_templates.py:731: No extensions configured in tenant
SKIPPED [1] tests/integration/collections/test_lots.py:91: No second active user available for team tests
SKIPPED [1] tests/integration/collections/test_btdataset.py:23: created_by=USR226595 returned no datasets on this tenant (seeded DST1580)
SKIPPED [1] tests/integration/collections/test_reports.py:46: Report Queries not loaded into testing environment yet
SKIPPED [1] tests/integration/collections/test_teams.py:90: No second active user available for team tests
SKIPPED [1] tests/integration/collections/test_teams.py:116: No second active user available for team tests
SKIPPED [15] tests/integration/collections/test_chats.py: Chats API is not yet available in the test environment.
SKIPPED [1] tests/integration/collections/test_sds.py:105: Tenant cannot generate SDS for seeded formula: POST 'https://staging.albertinventdev.com/api/v2/documentgenerator/sds' failed with status code 422 (Unprocessable Entity). Errors: [{'msg': 'ERROR_MISSING_INFO_CAS', 'casIDs': ['SDK-Test-456337f9-8491-444b-bf1b-542a86bf73e2-64-17-5']}]
SKIPPED [1] tests/integration/collections/test_users.py:92: No search hits could be hydrated (stale index IDs)
SKIPPED [1] tests/integration/collections/test_files.py:33: Breakthrough file namespace not available or upload not visible
SKIPPED [1] tests/integration/resources/test_sheets.py:221: Seeded Process Design has no rows to reference
XFAIL tests/integration/collections/test_design_runs.py::test_create_optimization_returns_generate_insight@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_create_doe_returns_smart_doe_insight@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_returns_response@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_doe_returns_response@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_create_optimization_accepts_weighted_objectives@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_accepts_weighted_objectives@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_accepts_plain_criterion@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_treats_a_null_weight_as_unweighted@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_smart_datasets.py::test_smart_dataset_get_data@datatemplates - No DWH available in TEN0 test environment.
XFAIL tests/integration/collections/test_smart_datasets.py::test_smart_dataset_get_data_with_filters@datatemplates - No DWH available in TEN0 test environment.
XFAIL tests/integration/collections/test_tasks.py::test_get_and_set_block_rules@tasks - increased intervals is not live on ten0 test env
XFAIL tests/integration/collections/test_tasks.py::test_create_with_combinations_integration@tasks - increased intervals is not live on ten0 test env
XFAIL tests/integration/collections/test_activities.py::test_activity_search - GET /api/v3/activities/search 500 OpenSearch on TEN0 staging: https://linear.app/albert-invent/issue/SEA-221
XPASS tests/integration/collections/test_smart_datasets.py::test_smart_dataset_create_with_build@datatemplates - No DWH available in TEN0 test environment.
XPASS tests/integration/collections/test_batch_data.py::test_create_batch_data@tasks - Batch data creation is currently not idempotent, so this test may fail if batch data already exists for the task.
XPASS tests/integration/collections/test_targets.py::test_target_create_with_between_parameter_filter@datatemplates - Requires api-targets backend to accept operator/value-pair TargetParameter.value (ML-1207). Remove decorator once deployed.
XPASS tests/integration/collections/test_substance_v4.py::test_search_pagination@projects - api-substance-v4 search pagination intermittently returns duplicate items across pages (MoleculeEngineering/api-substance-v4#57).
XPASS tests/integration/collections/test_tasks.py::test_generate_block_combinations_integration@tasks - increased intervals is not live on ten0 test env
= 2 failed, 354 passed, 37 skipped, 13 xfailed, 5 xpassed, 36 warnings in 608.45s (0:10:08) =

@lkubie

lkubie commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

CircleCI Integration Tests failed

Branch: cakeagents/ai-2153 (c5a8537)
Build: https://circleci.com/gh/albert-labs/albert-python/8748

=========================== short test summary info ============================
FAILED tests/integration/collections/test_personalization.py::test_personalization_crud@projects - pydantic_core._pydantic_core.ValidationError: 1 validation error for Personalization
category
  Field required [type=missing, input_value={'id': 'USP1325', 'parent...Personalization Target'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.13/v/missing
FAILED tests/integration/collections/test_projects.py::test_star_get_starred_and_unstar_project@projects - pydantic_core._pydantic_core.ValidationError: 1 validation error for Personalization
category
  Field required [type=missing, input_value={'id': 'USP1326', 'parent...b5b8 - Project to Star'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.13/v/missing
SKIPPED [10] tests/integration/collections/test_cas.py: CAS collection is deprecated in favor of Substance v4; the testing tenant has migrated to substance_v4.
SKIPPED [1] tests/integration/collections/test_data_templates.py:193: No eligible user returned by users.search() for ACL update.
SKIPPED [1] tests/integration/collections/test_inventory.py:210: LLM search is currently not working as expected.
SKIPPED [1] tests/integration/collections/test_data_templates.py:731: No extensions configured in tenant
SKIPPED [1] tests/integration/collections/test_lots.py:91: No second active user available for team tests
SKIPPED [1] tests/integration/collections/test_btdataset.py:23: created_by=USR226595 returned no datasets on this tenant (seeded DST1582)
SKIPPED [1] tests/integration/collections/test_reports.py:46: Report Queries not loaded into testing environment yet
SKIPPED [1] tests/integration/collections/test_sds.py:105: Tenant cannot generate SDS for seeded formula: POST 'https://staging.albertinventdev.com/api/v2/documentgenerator/sds' failed with status code 422 (Unprocessable Entity). Errors: [{'msg': 'ERROR_MISSING_INFO_CAS', 'casIDs': ['SDK-Test-103eda59-2f76-40a2-bb51-ffdfb40eb207-64-17-5']}]
SKIPPED [1] tests/integration/collections/test_teams.py:90: No second active user available for team tests
SKIPPED [1] tests/integration/collections/test_teams.py:116: No second active user available for team tests
SKIPPED [15] tests/integration/collections/test_chats.py: Chats API is not yet available in the test environment.
SKIPPED [1] tests/integration/collections/test_users.py:92: No search hits could be hydrated (stale index IDs)
SKIPPED [1] tests/integration/collections/test_files.py:33: Breakthrough file namespace not available or upload not visible
SKIPPED [1] tests/integration/resources/test_sheets.py:221: Seeded Process Design has no rows to reference
XFAIL tests/integration/collections/test_design_runs.py::test_create_optimization_returns_generate_insight@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_create_doe_returns_smart_doe_insight@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_returns_response@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_doe_returns_response@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_create_optimization_accepts_weighted_objectives@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_accepts_weighted_objectives@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_accepts_plain_criterion@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_treats_a_null_weight_as_unweighted@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_smart_datasets.py::test_smart_dataset_get_data@datatemplates - No DWH available in TEN0 test environment.
XFAIL tests/integration/collections/test_smart_datasets.py::test_smart_dataset_get_data_with_filters@datatemplates - No DWH available in TEN0 test environment.
XFAIL tests/integration/collections/test_tasks.py::test_get_and_set_block_rules@tasks - increased intervals is not live on ten0 test env
XFAIL tests/integration/collections/test_tasks.py::test_create_with_combinations_integration@tasks - increased intervals is not live on ten0 test env
XFAIL tests/integration/collections/test_activities.py::test_activity_search - GET /api/v3/activities/search 500 OpenSearch on TEN0 staging: https://linear.app/albert-invent/issue/SEA-221
XPASS tests/integration/collections/test_smart_datasets.py::test_smart_dataset_create_with_build@datatemplates - No DWH available in TEN0 test environment.
XPASS tests/integration/collections/test_batch_data.py::test_create_batch_data@tasks - Batch data creation is currently not idempotent, so this test may fail if batch data already exists for the task.
XPASS tests/integration/collections/test_targets.py::test_target_create_with_between_parameter_filter@datatemplates - Requires api-targets backend to accept operator/value-pair TargetParameter.value (ML-1207). Remove decorator once deployed.
XPASS tests/integration/collections/test_substance_v4.py::test_search_pagination@projects - api-substance-v4 search pagination intermittently returns duplicate items across pages (MoleculeEngineering/api-substance-v4#57).
XPASS tests/integration/collections/test_tasks.py::test_generate_block_combinations_integration@tasks - increased intervals is not live on ten0 test env
= 2 failed, 354 passed, 37 skipped, 13 xfailed, 5 xpassed, 36 warnings in 503.11s (0:08:23) =

The create call returns {id, parentId, savedId, savedName} with no
category key, so Personalization(**response) raised a validation error
in create() and projects.star(). The category just sent is authoritative;
setdefault it onto the response before validating. Refs AI-2153.
@claude

claude Bot commented Sep 30, 2026

Copy link
Copy Markdown

Looks good - no bugs or correctness issues found.

@lkubie

lkubie commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

CircleCI Integration Tests failed

Branch: cakeagents/ai-2153 (93201e8)
Build: https://circleci.com/gh/albert-labs/albert-python/8750

=========================== short test summary info ============================
FAILED tests/integration/collections/test_personalization.py::test_personalization_crud@projects - albert.exceptions.BadRequestError: GET 'https://staging.albertinventdev.com/api/v3/personalization?limit=200&savedId=PROMO323028' failed with status code 400 (Bad Request). Errors: [{'msg': 'Unknown query parameter &#x27;savedId&#x27;', 'type': 'query'}]
Body:
None
SKIPPED [10] tests/integration/collections/test_cas.py: CAS collection is deprecated in favor of Substance v4; the testing tenant has migrated to substance_v4.
SKIPPED [1] tests/integration/collections/test_data_templates.py:193: No eligible user returned by users.search() for ACL update.
SKIPPED [1] tests/integration/collections/test_inventory.py:210: LLM search is currently not working as expected.
SKIPPED [1] tests/integration/collections/test_data_templates.py:731: No extensions configured in tenant
SKIPPED [1] tests/integration/collections/test_lots.py:91: No second active user available for team tests
SKIPPED [1] tests/integration/collections/test_btdataset.py:23: created_by=USR226595 returned no datasets on this tenant (seeded DST1583)
SKIPPED [1] tests/integration/collections/test_reports.py:46: Report Queries not loaded into testing environment yet
SKIPPED [1] tests/integration/collections/test_teams.py:90: No second active user available for team tests
SKIPPED [1] tests/integration/collections/test_teams.py:116: No second active user available for team tests
SKIPPED [15] tests/integration/collections/test_chats.py: Chats API is not yet available in the test environment.
SKIPPED [1] tests/integration/collections/test_sds.py:105: Tenant cannot generate SDS for seeded formula: POST 'https://staging.albertinventdev.com/api/v2/documentgenerator/sds' failed with status code 422 (Unprocessable Entity). Errors: [{'msg': 'ERROR_MISSING_INFO_CAS', 'casIDs': ['SDK-Test-631f3837-0ac6-4ae0-b209-dcf4428e1e8b-64-17-5']}]
SKIPPED [1] tests/integration/collections/test_users.py:92: No search hits could be hydrated (stale index IDs)
SKIPPED [1] tests/integration/collections/test_files.py:33: Breakthrough file namespace not available or upload not visible
SKIPPED [1] tests/integration/resources/test_sheets.py:221: Seeded Process Design has no rows to reference
XFAIL tests/integration/collections/test_design_runs.py::test_create_optimization_returns_generate_insight@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_create_doe_returns_smart_doe_insight@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_returns_response@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_doe_returns_response@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_create_optimization_accepts_weighted_objectives@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_accepts_weighted_objectives@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_accepts_plain_criterion@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_design_runs.py::test_validate_optimization_treats_a_null_weight_as_unweighted@datatemplates - api-designruns is not live in the TEN0 test environment.
XFAIL tests/integration/collections/test_smart_datasets.py::test_smart_dataset_get_data@datatemplates - No DWH available in TEN0 test environment.
XFAIL tests/integration/collections/test_smart_datasets.py::test_smart_dataset_get_data_with_filters@datatemplates - No DWH available in TEN0 test environment.
XFAIL tests/integration/collections/test_tasks.py::test_get_and_set_block_rules@tasks - increased intervals is not live on ten0 test env
XFAIL tests/integration/collections/test_tasks.py::test_create_with_combinations_integration@tasks - increased intervals is not live on ten0 test env
XFAIL tests/integration/collections/test_activities.py::test_activity_search - GET /api/v3/activities/search 500 OpenSearch on TEN0 staging: https://linear.app/albert-invent/issue/SEA-221
XPASS tests/integration/collections/test_smart_datasets.py::test_smart_dataset_create_with_build@datatemplates - No DWH available in TEN0 test environment.
XPASS tests/integration/collections/test_batch_data.py::test_create_batch_data@tasks - Batch data creation is currently not idempotent, so this test may fail if batch data already exists for the task.
XPASS tests/integration/collections/test_targets.py::test_target_create_with_between_parameter_filter@datatemplates - Requires api-targets backend to accept operator/value-pair TargetParameter.value (ML-1207). Remove decorator once deployed.
XPASS tests/integration/collections/test_substance_v4.py::test_search_pagination@projects - api-substance-v4 search pagination intermittently returns duplicate items across pages (MoleculeEngineering/api-substance-v4#57).
XPASS tests/integration/collections/test_tasks.py::test_generate_block_combinations_integration@tasks - increased intervals is not live on ten0 test env
= 1 failed, 355 passed, 37 skipped, 13 xfailed, 5 xpassed, 36 warnings in 552.91s (0:09:12) =

The handler supports a savedId query, but the deployed API spec
(rest/api.yaml) does not declare it, so the gateway rejects the request
with "Unknown query parameter 'savedId'". Remove the parameter until the
backend declares it; listing is by createdBy (current user by default).
Refs AI-2153.
@claude

claude Bot commented Sep 30, 2026

Copy link
Copy Markdown

Code Review

Issues Found

  • src/albert/collections/personalization.py (get_all): The KEY-mode AlbertPaginator relies on the default _response_items, which reads only data["Items"] / data["items"]. Per OPINIONS.md, if this endpoint returns its list under any other key, every page looks empty and iteration stops immediately, silently breaking get_all, get_starred, and unstar. The integration tests that would catch this (test_personalization.py, test_star_get_starred_and_unstar_project) were not run in the authoring environment. Please run "uv run pytest tests/integration/collections/test_projects.py tests/integration/collections/test_personalization.py -v -n 4" before merge; if the list key is not Items/items, override _response_items in a paginator subclass.

  • src/albert/collections/personalization.py (create inline comment): The comment uses the banned term "response". AGENTS.md asks that code comments stay free of these terms where a caller-neutral phrasing exists.

Summary

2 issue(s) found. No confirmed logic bugs; the implementation mirrors the users.get_all pattern correctly. The main risk is the unverified pagination response key on a brand-new endpoint whose integration tests were not executed, confirm before merging.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants