projectdavid-orm 1.9.1__tar.gz → 1.11.0__tar.gz

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.
Files changed (26) hide show
  1. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/CHANGELOG.md +14 -0
  2. {projectdavid_orm-1.9.1/src/projectdavid_orm.egg-info → projectdavid_orm-1.11.0}/PKG-INFO +1 -1
  3. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/pyproject.toml +1 -1
  4. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm/projectdavid_orm/models.py +207 -0
  5. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0/src/projectdavid_orm.egg-info}/PKG-INFO +1 -1
  6. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/LICENSE +0 -0
  7. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/MANIFEST.in +0 -0
  8. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/README.md +0 -0
  9. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/setup.cfg +0 -0
  10. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_common.egg-info/PKG-INFO +0 -0
  11. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_common.egg-info/SOURCES.txt +0 -0
  12. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_common.egg-info/dependency_links.txt +0 -0
  13. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_common.egg-info/entry_points.txt +0 -0
  14. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_common.egg-info/requires.txt +0 -0
  15. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_common.egg-info/top_level.txt +0 -0
  16. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm/__init__.py +0 -0
  17. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm/constants/__init__.py +0 -0
  18. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm/ormInterface.py +0 -0
  19. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm/projectdavid_orm/__init__.py +0 -0
  20. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm/projectdavid_orm/base.py +0 -0
  21. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm/utilities/__init__.py +0 -0
  22. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm.egg-info/SOURCES.txt +0 -0
  23. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm.egg-info/dependency_links.txt +0 -0
  24. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm.egg-info/requires.txt +0 -0
  25. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/src/projectdavid_orm.egg-info/top_level.txt +0 -0
  26. {projectdavid_orm-1.9.1 → projectdavid_orm-1.11.0}/tests/test_clients.py +0 -0
@@ -1,3 +1,17 @@
1
+ # [1.11.0](https://github.com/project-david-ai/projectdavid-orm/compare/v1.10.0...v1.11.0) (2026-09-27)
2
+
3
+
4
+ ### Features
5
+
6
+ * add tenant credential persistence ([d222bc0](https://github.com/project-david-ai/projectdavid-orm/commit/d222bc0764dfb10ced00006b68a06c6a55d1b508))
7
+
8
+ # [1.10.0](https://github.com/project-david-ai/projectdavid-orm/compare/v1.9.1...v1.10.0) (2026-09-26)
9
+
10
+
11
+ ### Features
12
+
13
+ * add MCP registration persistence models ([61867c1](https://github.com/project-david-ai/projectdavid-orm/commit/61867c139ed1fa2ca1de3d263a5a77dabf0242dd))
14
+
1
15
  ## [1.9.1](https://github.com/project-david-ai/projectdavid-orm/compare/v1.9.0...v1.9.1) (2026-08-27)
2
16
 
3
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: projectdavid-orm
3
- Version: 1.9.1
3
+ Version: 1.11.0
4
4
  Summary: Shared SQLAlchemy ORM models for ProjectDavid services
5
5
  Author-email: "Francis N." <engineering@projectdavid.co.uk>
6
6
  License: PolyForm Noncommercial License 1.0.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "projectdavid-orm"
7
- version = "1.9.1"
7
+ version = "1.11.0"
8
8
  description = "Shared SQLAlchemy ORM models for ProjectDavid services"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -180,6 +180,20 @@ class User(Base):
180
180
 
181
181
  audit_logs = relationship("AuditLog", back_populates="user", lazy="dynamic")
182
182
 
183
+ credentials = relationship(
184
+ "Credential",
185
+ back_populates="owner",
186
+ cascade="all, delete-orphan",
187
+ lazy="select",
188
+ )
189
+
190
+ mcp_server_registrations = relationship(
191
+ "McpServerRegistration",
192
+ back_populates="owner",
193
+ cascade="all, delete-orphan",
194
+ lazy="select",
195
+ )
196
+
183
197
  __table_args__ = (
184
198
  UniqueConstraint(
185
199
  "oauth_provider", "provider_user_id", name="uq_user_oauth_provider_id"
@@ -489,6 +503,199 @@ class Assistant(Base):
489
503
  lazy="select",
490
504
  )
491
505
 
506
+ mcp_tools = relationship(
507
+ "AssistantMcpTool",
508
+ back_populates="assistant",
509
+ cascade="all, delete-orphan",
510
+ lazy="select",
511
+ )
512
+
513
+
514
+ class Credential(Base):
515
+ """Tenant-owned encrypted credential material.
516
+
517
+ Plaintext credentials are never persisted. Decryption is owned by
518
+ the application credential service and requires deployment-supplied
519
+ root key material.
520
+ """
521
+
522
+ __tablename__ = "credentials"
523
+
524
+ id = Column(String(64), primary_key=True, index=True)
525
+
526
+ owner_id = Column(
527
+ String(64),
528
+ ForeignKey("users.id", ondelete="CASCADE"),
529
+ nullable=False,
530
+ index=True,
531
+ )
532
+
533
+ kind = Column(String(32), nullable=False)
534
+ encrypted_payload = Column(Text, nullable=False)
535
+ encryption_version = Column(
536
+ Integer,
537
+ nullable=False,
538
+ default=1,
539
+ server_default="1",
540
+ )
541
+
542
+ created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
543
+ updated_at = Column(
544
+ DateTime,
545
+ nullable=False,
546
+ default=datetime.utcnow,
547
+ onupdate=datetime.utcnow,
548
+ )
549
+
550
+ owner = relationship("User", back_populates="credentials")
551
+
552
+ mcp_server_registrations = relationship(
553
+ "McpServerRegistration",
554
+ back_populates="credential",
555
+ lazy="select",
556
+ )
557
+
558
+ __table_args__ = (Index("idx_credentials_owner_kind", "owner_id", "kind"),)
559
+
560
+
561
+ class McpServerRegistration(Base):
562
+ """A user-owned remote MCP server registration.
563
+
564
+ Authentication references generic tenant-owned encrypted credentials.
565
+ Raw credential material is never persisted on the registration itself.
566
+ """
567
+
568
+ __tablename__ = "mcp_server_registrations"
569
+
570
+ id = Column(String(64), primary_key=True, index=True)
571
+
572
+ owner_id = Column(
573
+ String(64),
574
+ ForeignKey("users.id", ondelete="CASCADE"),
575
+ nullable=False,
576
+ index=True,
577
+ )
578
+
579
+ name = Column(String(128), nullable=False)
580
+
581
+ url = Column(Text, nullable=False)
582
+ normalized_url = Column(Text, nullable=False)
583
+
584
+ identity_key = Column(
585
+ String(64),
586
+ nullable=False,
587
+ comment=(
588
+ "Stable SHA-256 identity derived from transport + normalized URL. "
589
+ "Combined with owner_id to make registration idempotent."
590
+ ),
591
+ )
592
+
593
+ transport = Column(
594
+ String(32),
595
+ nullable=False,
596
+ default="streamable_http",
597
+ server_default="streamable_http",
598
+ )
599
+
600
+ auth_type = Column(
601
+ String(32),
602
+ nullable=False,
603
+ default="none",
604
+ server_default="none",
605
+ )
606
+
607
+ credential_id = Column(
608
+ String(64),
609
+ ForeignKey("credentials.id", ondelete="RESTRICT"),
610
+ nullable=True,
611
+ index=True,
612
+ )
613
+
614
+ timeout_seconds = Column(Float, nullable=False, default=30.0, server_default="30")
615
+
616
+ enabled = Column(Boolean, nullable=False, default=True, server_default="1")
617
+
618
+ created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
619
+ updated_at = Column(
620
+ DateTime,
621
+ nullable=False,
622
+ default=datetime.utcnow,
623
+ onupdate=datetime.utcnow,
624
+ )
625
+
626
+ owner = relationship("User", back_populates="mcp_server_registrations")
627
+
628
+ credential = relationship(
629
+ "Credential",
630
+ back_populates="mcp_server_registrations",
631
+ )
632
+
633
+ assistant_tools = relationship(
634
+ "AssistantMcpTool",
635
+ back_populates="registration",
636
+ cascade="all, delete-orphan",
637
+ lazy="select",
638
+ )
639
+
640
+ __table_args__ = (
641
+ UniqueConstraint(
642
+ "owner_id",
643
+ "identity_key",
644
+ name="uq_mcp_registration_owner_identity",
645
+ ),
646
+ Index("idx_mcp_registration_owner_enabled", "owner_id", "enabled"),
647
+ )
648
+
649
+
650
+ class AssistantMcpTool(Base):
651
+ """Assistant-specific provenance for one discovered MCP tool."""
652
+
653
+ __tablename__ = "assistant_mcp_tools"
654
+
655
+ id = Column(String(64), primary_key=True, index=True)
656
+
657
+ assistant_id = Column(
658
+ String(64),
659
+ ForeignKey("assistants.id", ondelete="CASCADE"),
660
+ nullable=False,
661
+ index=True,
662
+ )
663
+
664
+ registration_id = Column(
665
+ String(64),
666
+ ForeignKey("mcp_server_registrations.id", ondelete="CASCADE"),
667
+ nullable=False,
668
+ index=True,
669
+ )
670
+
671
+ remote_name = Column(String(255), nullable=False)
672
+ canonical_id = Column(String(512), nullable=False)
673
+ provider_name = Column(String(64), nullable=False)
674
+
675
+ enabled = Column(Boolean, nullable=False, default=True, server_default="1")
676
+ created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
677
+
678
+ assistant = relationship("Assistant", back_populates="mcp_tools")
679
+ registration = relationship(
680
+ "McpServerRegistration",
681
+ back_populates="assistant_tools",
682
+ )
683
+
684
+ __table_args__ = (
685
+ UniqueConstraint(
686
+ "assistant_id",
687
+ "registration_id",
688
+ "remote_name",
689
+ name="uq_assistant_mcp_remote_tool",
690
+ ),
691
+ UniqueConstraint(
692
+ "assistant_id",
693
+ "provider_name",
694
+ name="uq_assistant_mcp_provider_name",
695
+ ),
696
+ Index("idx_assistant_mcp_registration", "registration_id"),
697
+ )
698
+
492
699
 
493
700
  class Action(Base):
494
701
  __tablename__ = "actions"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: projectdavid-orm
3
- Version: 1.9.1
3
+ Version: 1.11.0
4
4
  Summary: Shared SQLAlchemy ORM models for ProjectDavid services
5
5
  Author-email: "Francis N." <engineering@projectdavid.co.uk>
6
6
  License: PolyForm Noncommercial License 1.0.0