Coverage for apps/integrations/models.py: 93%

44 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-11-04 14:06 +0000

1"""Integration + credential models (design D1). Secrets are stored as Fernet blobs in 

2``secret_enc`` and are never exposed over the API (design D2).""" 

3 

4from __future__ import annotations 

5 

6from django.conf import settings 

7from django.db import models 

8 

9 

10class OrgIntegration(models.Model): 

11 """Per-org enablement + non-secret config + encrypted secret for a catalog provider.""" 

12 

13 org_unit = models.ForeignKey( 

14 "accounts.OrgUnit", on_delete=models.CASCADE, related_name="integrations" 

15 ) 

16 provider = models.CharField(max_length=40) # catalog code 

17 enabled = models.BooleanField(default=False) 

18 config = models.JSONField(default=dict, blank=True) 

19 secret_enc = models.BinaryField(null=True, blank=True) 

20 created_at = models.DateTimeField(auto_now_add=True) 

21 updated_at = models.DateTimeField(auto_now=True) 

22 

23 class Meta: 

24 db_table = "org_integrations" 

25 unique_together = ("org_unit", "provider") 

26 

27 def __str__(self) -> str: 

28 return f"{self.org_unit_id}:{self.provider} ({'on' if self.enabled else 'off'})" 

29 

30 

31class UserCredential(models.Model): 

32 """Per-user credential (credit login, DU/LPA ownership accounts) — encrypted secret.""" 

33 

34 user = models.ForeignKey( 

35 settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="credentials" 

36 ) 

37 provider = models.CharField(max_length=40) # catalog code 

38 config = models.JSONField(default=dict, blank=True) 

39 secret_enc = models.BinaryField(null=True, blank=True) 

40 created_at = models.DateTimeField(auto_now_add=True) 

41 updated_at = models.DateTimeField(auto_now=True) 

42 

43 class Meta: 

44 db_table = "user_credentials" 

45 unique_together = ("user", "provider") 

46 

47 def __str__(self) -> str: 

48 return f"{self.user_id}:{self.provider}" 

49 

50 

51class Lender(models.Model): 

52 """Per-org approved lender with per-capability flags (spec §8.6 lender integrations).""" 

53 

54 org_unit = models.ForeignKey( 

55 "accounts.OrgUnit", on_delete=models.CASCADE, related_name="lenders" 

56 ) 

57 name = models.CharField(max_length=255) 

58 pricing_ind = models.BooleanField(default=False) 

59 registration_ind = models.BooleanField(default=False) 

60 doc_submission_ind = models.BooleanField(default=False) 

61 auto_sync_ind = models.BooleanField(default=False) 

62 authorization_ind = models.BooleanField(default=False) 

63 is_active = models.BooleanField(default=True) 

64 created_at = models.DateTimeField(auto_now_add=True) 

65 updated_at = models.DateTimeField(auto_now=True) 

66 

67 class Meta: 

68 db_table = "lenders" 

69 unique_together = ("org_unit", "name") 

70 

71 def __str__(self) -> str: 

72 return f"{self.name} (org {self.org_unit_id})"