better-notion 2.1.3__py3-none-any.whl → 2.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -423,8 +423,10 @@ class TaskSchema:
423
423
  def get_schema() -> Dict[str, Dict[str, Any]]:
424
424
  """Return Notion database schema for Tasks.
425
425
 
426
- Note: "Dependencies" self-referential relation is NOT included here.
427
- It will be added after the database is created via database.update().
426
+ Note: The following properties are NOT included here and will be added
427
+ after database creation via database.update():
428
+ - "Dependencies": Self-referential relation (requires database's own ID)
429
+ - "Related Work Issue": Relation to Work Issues (Work Issues created after Tasks)
428
430
  """
429
431
  return {
430
432
  "Title": PropertyBuilder.title("Title"),
@@ -462,8 +464,6 @@ class TaskSchema:
462
464
  SelectOption.option("Low", "blue"),
463
465
  ],
464
466
  ),
465
- # Related Work Issue: Relation to Work Issues (will be updated after database creation)
466
- "Related Work Issue": PropertyBuilder.relation("Related Work Issue", dual_property=False),
467
467
  "Estimated Hours": PropertyBuilder.number("Estimated Hours"),
468
468
  "Actual Hours": PropertyBuilder.number("Actual Hours"),
469
469
  "Assignee": PropertyBuilder.people("Assignee"),
@@ -522,7 +522,13 @@ class WorkIssueSchema:
522
522
 
523
523
  @staticmethod
524
524
  def get_schema() -> Dict[str, Dict[str, Any]]:
525
- """Return Notion database schema for Work Issues."""
525
+ """Return Notion database schema for Work Issues.
526
+
527
+ Note: The following properties are NOT included here and will be added
528
+ after database creation via database.update():
529
+ - "Blocking Tasks": Relation to Tasks (added in post-processing)
530
+ - "Caused Incidents": Relation to Incidents (Incidents created after Work Issues)
531
+ """
526
532
  return {
527
533
  "Title": PropertyBuilder.title("Title"),
528
534
  "Project": PropertyBuilder.relation("Project"),
@@ -561,10 +567,6 @@ class WorkIssueSchema:
561
567
  "Proposed Solution": PropertyBuilder.text("Proposed Solution"),
562
568
  "Related Idea": PropertyBuilder.relation("Related Idea", dual_property=False),
563
569
  "Fix Tasks": PropertyBuilder.relation("Fix Tasks", dual_property=False),
564
- # Blocking Tasks: Tasks blocked by this work issue (will be updated after database creation)
565
- "Blocking Tasks": PropertyBuilder.relation("Blocking Tasks", dual_property=False),
566
- # Caused Incidents: Incidents caused by this work issue (will be updated after database creation)
567
- "Caused Incidents": PropertyBuilder.relation("Caused Incidents", dual_property=False),
568
570
  }
569
571
 
570
572
 
@@ -573,7 +575,11 @@ class IncidentSchema:
573
575
 
574
576
  @staticmethod
575
577
  def get_schema() -> Dict[str, Dict[str, Any]]:
576
- """Return Notion database schema for Incidents."""
578
+ """Return Notion database schema for Incidents.
579
+
580
+ Note: "Root Cause Work Issue" is NOT included here and will be added
581
+ after database creation via database.update() for consistency.
582
+ """
577
583
  return {
578
584
  "Title": PropertyBuilder.title("Title"),
579
585
  "Project": PropertyBuilder.relation("Project"),
@@ -607,8 +613,6 @@ class IncidentSchema:
607
613
  ],
608
614
  ),
609
615
  "Fix Task": PropertyBuilder.relation("Fix Task", dual_property=False),
610
- # Root Cause Work Issue: Relation to Work Issues (will be updated after database creation)
611
- "Root Cause Work Issue": PropertyBuilder.relation("Root Cause Work Issue", dual_property=False),
612
616
  "Root Cause": PropertyBuilder.text("Root Cause"),
613
617
  "Detected Date": PropertyBuilder.date("Detected Date"),
614
618
  "Resolved Date": PropertyBuilder.date("Resolved Date"),
@@ -169,6 +169,14 @@ class WorkspaceInitializer:
169
169
  # Update cross-database relations that require both databases to exist
170
170
  await self._update_cross_database_relations()
171
171
 
172
+ # Add self-referential Dependencies relation to Tasks database
173
+ if "tasks" in self._database_ids:
174
+ await self._update_relation(
175
+ self._database_ids["tasks"],
176
+ "Dependencies",
177
+ self._database_ids["tasks"] # Self-reference
178
+ )
179
+
172
180
  # Save workspace metadata
173
181
  self.save_database_ids()
174
182
 
@@ -249,7 +257,7 @@ class WorkspaceInitializer:
249
257
  )
250
258
 
251
259
  async def _create_tasks_db(self, parent: Page) -> None:
252
- """Create Tasks database with relations to Versions (self-referencing for dependencies)."""
260
+ """Create Tasks database with relations to Versions."""
253
261
  schema = TaskSchema.get_schema()
254
262
 
255
263
  # Update relations with Versions database ID
@@ -259,8 +267,6 @@ class WorkspaceInitializer:
259
267
  "versions"
260
268
  ]
261
269
 
262
- # Tasks reference themselves for dependencies
263
- # Will be updated after database creation
264
270
  db = await self._client.databases.create(
265
271
  parent=parent,
266
272
  title="Tasks",
@@ -269,9 +275,6 @@ class WorkspaceInitializer:
269
275
 
270
276
  self._database_ids["tasks"] = db.id
271
277
 
272
- # Update self-referential relations
273
- await self._update_self_relations(db.id)
274
-
275
278
  # Update Versions database with reverse relation
276
279
  await self._add_reverse_relation(
277
280
  self._database_ids["versions"],
@@ -397,50 +400,16 @@ class WorkspaceInitializer:
397
400
  logger.warning(f"Failed to delete database {database_id}: {str(e)}")
398
401
  # Continue with other deletions even if this one fails
399
402
 
400
- async def _update_self_relations(self, database_id: str) -> None:
401
- """Add self-referential Dependencies relation to Tasks database.
402
-
403
- The Dependencies property cannot be included in the initial schema
404
- because it requires the database's own ID. This method adds it
405
- after the database is created.
406
-
407
- Args:
408
- database_id: ID of the Tasks database
409
- """
410
- # Get the current database schema
411
- db = await self._client.databases.get(database_id)
412
- schema = db.schema
413
-
414
- # Add the Dependencies self-referential relation
415
- # This creates a relation from Tasks to Tasks itself
416
- schema["Dependencies"] = {
417
- "relation": {
418
- "database_id": database_id, # Self-reference
419
- "type": "dual_property",
420
- "dual_property": {
421
- "synced_property_name": "Dependent Tasks",
422
- "synced_property_type": "relation"
423
- }
424
- }
425
- }
426
-
427
- # Update the database schema via API
428
- await self._client._api._request(
429
- "PATCH",
430
- f"/databases/{database_id}",
431
- json={"properties": schema}
432
- )
433
-
434
- logger.info(f"Added Dependencies self-referential relation to Tasks database {database_id}")
435
-
436
403
  async def _update_cross_database_relations(self) -> None:
437
404
  """Update cross-database relations after all databases are created.
438
405
 
439
- This updates:
440
- - Tasks: Related Work Issue -> Work Issues
441
- - Work Issues: Blocking Tasks -> Tasks
442
- - Work Issues: Caused Incidents -> Incidents
406
+ This adds:
407
+ - Tasks: Dependencies (self-referential), Related Work Issue -> Work Issues
408
+ - Work Issues: Blocking Tasks -> Tasks, Caused Incidents -> Incidents
443
409
  - Incidents: Root Cause Work Issue -> Work Issues
410
+
411
+ All these properties are added AFTER database creation because they
412
+ reference databases that may not exist yet during initial creation.
444
413
  """
445
414
  if "tasks" in self._database_ids:
446
415
  await self._update_relation(
@@ -476,7 +445,7 @@ class WorkspaceInitializer:
476
445
  property_name: str,
477
446
  target_database_id: Optional[str],
478
447
  ) -> None:
479
- """Update a relation property to point to the target database.
448
+ """Add or update a relation property to point to the target database.
480
449
 
481
450
  Args:
482
451
  database_id: Database to update
@@ -491,20 +460,92 @@ class WorkspaceInitializer:
491
460
  db = await self._client.databases.get(database_id)
492
461
  schema = db.schema
493
462
 
494
- # Update the relation property
463
+ # Add or update the relation property
464
+ # Some properties (like Dependencies, Related Work Issue) are added AFTER
465
+ # database creation, so they may not exist in the initial schema
495
466
  if property_name in schema:
467
+ # Property exists, just update the database_id
496
468
  schema[property_name]["relation"]["database_id"] = target_database_id
469
+ else:
470
+ # Property doesn't exist, ADD it
471
+ # This handles cases where the property couldn't be in the initial schema
472
+ if property_name == "Dependencies":
473
+ # Self-referential relation
474
+ schema[property_name] = {
475
+ "relation": {
476
+ "database_id": database_id, # Self-reference
477
+ "type": "dual_property",
478
+ "dual_property": {
479
+ "synced_property_name": "Dependent Tasks",
480
+ "synced_property_type": "relation"
481
+ }
482
+ }
483
+ }
484
+ elif property_name == "Related Work Issue":
485
+ # Relation to Work Issues database
486
+ schema[property_name] = {
487
+ "relation": {
488
+ "database_id": target_database_id,
489
+ "type": "dual_property",
490
+ "dual_property": {
491
+ "synced_property_name": "Related Tasks",
492
+ "synced_property_type": "relation"
493
+ }
494
+ }
495
+ }
496
+ elif property_name == "Blocking Tasks":
497
+ # Relation from Work Issues to Tasks
498
+ schema[property_name] = {
499
+ "relation": {
500
+ "database_id": target_database_id,
501
+ "type": "dual_property",
502
+ "dual_property": {
503
+ "synced_property_name": "Blocked By Work Issue",
504
+ "synced_property_type": "relation"
505
+ }
506
+ }
507
+ }
508
+ elif property_name == "Caused Incidents":
509
+ # Relation from Work Issues to Incidents
510
+ schema[property_name] = {
511
+ "relation": {
512
+ "database_id": target_database_id,
513
+ "type": "dual_property",
514
+ "dual_property": {
515
+ "synced_property_name": "Root Cause Work Issue",
516
+ "synced_property_type": "relation"
517
+ }
518
+ }
519
+ }
520
+ elif property_name == "Root Cause Work Issue":
521
+ # Relation from Incidents to Work Issues
522
+ schema[property_name] = {
523
+ "relation": {
524
+ "database_id": target_database_id,
525
+ "type": "dual_property",
526
+ "dual_property": {
527
+ "synced_property_name": "Caused Incidents",
528
+ "synced_property_type": "relation"
529
+ }
530
+ }
531
+ }
532
+ else:
533
+ # Generic relation
534
+ schema[property_name] = {
535
+ "relation": {
536
+ "database_id": target_database_id,
537
+ "dual_property": {}
538
+ }
539
+ }
497
540
 
498
- # Update the database schema via API
499
- await self._client._api._request(
500
- "PATCH",
501
- f"/databases/{database_id}",
502
- json={"properties": schema}
503
- )
541
+ # Update the database schema via API
542
+ await self._client._api._request(
543
+ "PATCH",
544
+ f"/databases/{database_id}",
545
+ json={"properties": schema}
546
+ )
504
547
 
505
- logger.info(f"Updated {property_name} relation to {target_database_id}")
506
- else:
507
- logger.warning(f"Property {property_name} not found in database {database_id}")
548
+ logger.info(f"Added/Updated {property_name} relation to {target_database_id}")
508
549
 
509
550
  def save_database_ids(self, path: Optional[Path] = None) -> None:
510
551
  """Save workspace metadata (database IDs and workspace info) to config file.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: better-notion
3
- Version: 2.1.3
3
+ Version: 2.1.5
4
4
  Summary: A high-level Python SDK for the Notion API with developer experience in mind.
5
5
  Project-URL: Homepage, https://github.com/nesalia-inc/better-notion
6
6
  Project-URL: Documentation, https://github.com/nesalia-inc/better-notion#readme
@@ -130,11 +130,11 @@ better_notion/utils/agents/dependency_resolver.py,sha256=PfHHDIQztGih4LwylMb0_My
130
130
  better_notion/utils/agents/metadata.py,sha256=thQSXfYx9mWgmBud8HtlNTLr5SwH6E_O1AjSNSnMFoo,6614
131
131
  better_notion/utils/agents/project_context.py,sha256=aJlzy5H2rL4sAfW2jHL_3K2VkBJ4ihUhCRVolkpuO78,7477
132
132
  better_notion/utils/agents/rbac.py,sha256=8ZA8Y7wbOiVZDbpjpH7iC35SZrZ0jl4fcJ3xWCm3SsE,11820
133
- better_notion/utils/agents/schemas.py,sha256=pO4MiSaWzSOCZu6J3uZPH7mtMVpE2H3iDHzd6WH0wXc,22926
133
+ better_notion/utils/agents/schemas.py,sha256=2QF71tL-lt_n7u-oizVDMj4nd29fl8uUbhMKTWxNzr4,22721
134
134
  better_notion/utils/agents/state_machine.py,sha256=xUBEeDTbU1Xq-rsRo2sbr6AUYpYrV9DTHOtZT2cWES8,6699
135
- better_notion/utils/agents/workspace.py,sha256=W9MKf4b2fvoGCKHp8EuZROnr1tfmR3lS5GrmCuKrZQQ,22841
136
- better_notion-2.1.3.dist-info/METADATA,sha256=jQ5fHLFQ9DN3gfYKaiJuUMPIWjDhrC8VeIAQl_KxDMQ,11096
137
- better_notion-2.1.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
138
- better_notion-2.1.3.dist-info/entry_points.txt,sha256=D0bUcP7Z00Zyjxw7r2p29T95UrwioDO0aGDoHe9I6fo,55
139
- better_notion-2.1.3.dist-info/licenses/LICENSE,sha256=BAdN3JpgMY_y_fWqZSCFSvSbC2mTHP-BKDAzF5FXQAI,1069
140
- better_notion-2.1.3.dist-info/RECORD,,
135
+ better_notion/utils/agents/workspace.py,sha256=zmJ2BRklEBC9fzB1AudA33h-yvFYvm1iSR2huc60oE4,25007
136
+ better_notion-2.1.5.dist-info/METADATA,sha256=bF0A80PsoJc2QHKhiYMB14I89zMtUbrCz_LkzadHVGs,11096
137
+ better_notion-2.1.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
138
+ better_notion-2.1.5.dist-info/entry_points.txt,sha256=D0bUcP7Z00Zyjxw7r2p29T95UrwioDO0aGDoHe9I6fo,55
139
+ better_notion-2.1.5.dist-info/licenses/LICENSE,sha256=BAdN3JpgMY_y_fWqZSCFSvSbC2mTHP-BKDAzF5FXQAI,1069
140
+ better_notion-2.1.5.dist-info/RECORD,,