mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-06-29 07:43:32 +02:00
Merge pull request #610 from cisagov/nmb/model-timeline-docs
Model timeline documentation
This commit is contained in:
commit
b62ca2e85d
7 changed files with 518 additions and 82 deletions
149
docs/architecture/diagrams/model_timeline.md
Normal file
149
docs/architecture/diagrams/model_timeline.md
Normal file
|
@ -0,0 +1,149 @@
|
|||
# Data Model Timeline
|
||||
|
||||
This diagram connects the data models along with various workflow stages.
|
||||
|
||||
1. The applicant starts the process at `/register` interacting with the
|
||||
`DomainApplication` object.
|
||||
|
||||
2. The analyst approves the application using the `DomainApplication`'s
|
||||
`approve()` method which creates many related objects: `UserDomainRole`,
|
||||
`Domain`, and `DomainInformation`.
|
||||
|
||||
3. After the domain is approved, users interact with various
|
||||
`/domain/<id>/...` views which make changes to the `Domain`,
|
||||
`DomainInformation`, and `UserDomainRole` models. For inviting new users,
|
||||
there is a `DomainInvitation` model that allows people to be added to
|
||||
domains who are not already users.
|
||||
|
||||
A more complete diagram of the data models, their fields, and their
|
||||
relationships are in [models_diagram.md](./models_diagram.md), created with
|
||||
the `django-model2puml` plugin.
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>PlantUML source code</summary>
|
||||
To regenerate this image using Docker, run
|
||||
|
||||
```bash
|
||||
$ docker run -v $(pwd):$(pwd) -w $(pwd) -it plantuml/plantuml -tsvg model_timeline.md
|
||||
```
|
||||
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
|
||||
allowmixing
|
||||
left to right direction
|
||||
|
||||
class DomainApplication {
|
||||
Application for a domain
|
||||
--
|
||||
creator (User)
|
||||
investigator (User)
|
||||
authorizing_official (Contact)
|
||||
submitter (Contact)
|
||||
other_contacts (Contacts)
|
||||
requested_domain (Domain)
|
||||
current_websites (Websites)
|
||||
alternative_domains (Websites)
|
||||
--
|
||||
Request information...
|
||||
}
|
||||
|
||||
class User {
|
||||
Django's user class
|
||||
--
|
||||
...
|
||||
--
|
||||
}
|
||||
note left of User
|
||||
Created by DjangoOIDC
|
||||
when users arrive back
|
||||
from Login.gov
|
||||
|
||||
<b>username</b> is the Login UUID
|
||||
end note
|
||||
|
||||
DomainApplication -l- User : creator, investigator
|
||||
|
||||
class Contact {
|
||||
Contact info for a person
|
||||
--
|
||||
first_name
|
||||
middle_name
|
||||
last_name
|
||||
title
|
||||
email
|
||||
phone
|
||||
--
|
||||
}
|
||||
|
||||
DomainApplication *-r-* Contact : authorizing_official, submitter, other_contacts
|
||||
|
||||
class Domain {
|
||||
Approved domain
|
||||
--
|
||||
name
|
||||
is_active
|
||||
--
|
||||
<b>EPP methods</b>
|
||||
}
|
||||
|
||||
DomainApplication .right[#blue].> Domain : approve()
|
||||
|
||||
class DomainInformation {
|
||||
Registrar information on a domain
|
||||
--
|
||||
domain (Domain)
|
||||
domain_application (DomainApplication)
|
||||
security_email
|
||||
--
|
||||
Request information...
|
||||
}
|
||||
|
||||
DomainInformation -- Domain
|
||||
DomainInformation -- DomainApplication
|
||||
DomainApplication .[#blue].> DomainInformation : approve()
|
||||
|
||||
class UserDomainRole {
|
||||
Permissions
|
||||
--
|
||||
domain (Domain)
|
||||
user (User)
|
||||
role="ADMIN"
|
||||
--
|
||||
}
|
||||
UserDomainRole -- User
|
||||
UserDomainRole -- Domain
|
||||
DomainApplication .[#blue].> UserDomainRole : approve()
|
||||
|
||||
class DomainInvitation {
|
||||
Email invitations sent
|
||||
--
|
||||
email
|
||||
domain (Domain)
|
||||
status
|
||||
--
|
||||
}
|
||||
DomainInvitation -- Domain
|
||||
DomainInvitation .[#green].> UserDomainRole : User.first_login()
|
||||
|
||||
actor applicant #Red
|
||||
applicant -d-> DomainApplication : **/register**
|
||||
|
||||
actor analyst #Blue
|
||||
analyst -[#blue]-> DomainApplication : **approve()**
|
||||
|
||||
actor user1 #Green
|
||||
user1 -[#green]-> Domain : **/domain/<id>/nameservers**
|
||||
actor user2 #Green
|
||||
user2 -[#green]-> DomainInformation : **/domain/<id>/?????**
|
||||
actor user3 #Green
|
||||
user3 -right[#green]-> UserDomainRole : **/domain/<id>/users/add**
|
||||
user3 -right[#green]-> DomainInvitation : **/domain/<id>/users/add**
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
</details>
|
1
docs/architecture/diagrams/model_timeline.svg
Normal file
1
docs/architecture/diagrams/model_timeline.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 28 KiB |
275
docs/architecture/diagrams/models_diagram.md
Normal file
275
docs/architecture/diagrams/models_diagram.md
Normal file
|
@ -0,0 +1,275 @@
|
|||
# Complete model documentation
|
||||
|
||||
This is an auto-generated diagram of our data models generated with the
|
||||
[django-model2puml](https://github.com/sen-den/django-model2puml) library
|
||||
using the command
|
||||
|
||||
```bash
|
||||
$ docker compose app ./manage.py generate_puml --include registrar
|
||||
```
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>PlantUML source code</summary>
|
||||
|
||||
To regenerate this image using Docker, run
|
||||
|
||||
```bash
|
||||
$ docker run -v $(pwd):$(pwd) -w $(pwd) -it plantuml/plantuml -tsvg models_diagram.md
|
||||
```
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
class "registrar.Contact <Registrar>" as registrar.Contact #d6f4e9 {
|
||||
contact
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
~ user (OneToOneField)
|
||||
+ first_name (TextField)
|
||||
+ middle_name (TextField)
|
||||
+ last_name (TextField)
|
||||
+ title (TextField)
|
||||
+ email (TextField)
|
||||
+ phone (PhoneNumberField)
|
||||
--
|
||||
}
|
||||
registrar.Contact -- registrar.User
|
||||
|
||||
|
||||
class "registrar.DomainApplication <Registrar>" as registrar.DomainApplication #d6f4e9 {
|
||||
domain application
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
+ status (FSMField)
|
||||
~ creator (ForeignKey)
|
||||
~ investigator (ForeignKey)
|
||||
+ organization_type (CharField)
|
||||
+ federally_recognized_tribe (BooleanField)
|
||||
+ state_recognized_tribe (BooleanField)
|
||||
+ tribe_name (TextField)
|
||||
+ federal_agency (TextField)
|
||||
+ federal_type (CharField)
|
||||
+ is_election_board (BooleanField)
|
||||
+ organization_name (TextField)
|
||||
+ address_line1 (TextField)
|
||||
+ address_line2 (CharField)
|
||||
+ city (TextField)
|
||||
+ state_territory (CharField)
|
||||
+ zipcode (CharField)
|
||||
+ urbanization (TextField)
|
||||
+ type_of_work (TextField)
|
||||
+ more_organization_information (TextField)
|
||||
~ authorizing_official (ForeignKey)
|
||||
~ requested_domain (OneToOneField)
|
||||
~ submitter (ForeignKey)
|
||||
+ purpose (TextField)
|
||||
+ no_other_contacts_rationale (TextField)
|
||||
+ anything_else (TextField)
|
||||
+ is_policy_acknowledged (BooleanField)
|
||||
# current_websites (ManyToManyField)
|
||||
# alternative_domains (ManyToManyField)
|
||||
# other_contacts (ManyToManyField)
|
||||
--
|
||||
}
|
||||
registrar.DomainApplication -- registrar.User
|
||||
registrar.DomainApplication -- registrar.User
|
||||
registrar.DomainApplication -- registrar.Contact
|
||||
registrar.DomainApplication -- registrar.Domain
|
||||
registrar.DomainApplication -- registrar.Contact
|
||||
registrar.DomainApplication *--* registrar.Website
|
||||
registrar.DomainApplication *--* registrar.Website
|
||||
registrar.DomainApplication *--* registrar.Contact
|
||||
|
||||
|
||||
class "registrar.DomainInformation <Registrar>" as registrar.DomainInformation #d6f4e9 {
|
||||
domain information
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
~ creator (ForeignKey)
|
||||
~ domain_application (OneToOneField)
|
||||
+ organization_type (CharField)
|
||||
+ federally_recognized_tribe (BooleanField)
|
||||
+ state_recognized_tribe (BooleanField)
|
||||
+ tribe_name (TextField)
|
||||
+ federal_agency (TextField)
|
||||
+ federal_type (CharField)
|
||||
+ is_election_board (BooleanField)
|
||||
+ organization_name (TextField)
|
||||
+ address_line1 (TextField)
|
||||
+ address_line2 (CharField)
|
||||
+ city (TextField)
|
||||
+ state_territory (CharField)
|
||||
+ zipcode (CharField)
|
||||
+ urbanization (TextField)
|
||||
+ type_of_work (TextField)
|
||||
+ more_organization_information (TextField)
|
||||
~ authorizing_official (ForeignKey)
|
||||
~ domain (OneToOneField)
|
||||
~ submitter (ForeignKey)
|
||||
+ purpose (TextField)
|
||||
+ no_other_contacts_rationale (TextField)
|
||||
+ anything_else (TextField)
|
||||
+ is_policy_acknowledged (BooleanField)
|
||||
+ security_email (EmailField)
|
||||
# other_contacts (ManyToManyField)
|
||||
--
|
||||
}
|
||||
registrar.DomainInformation -- registrar.User
|
||||
registrar.DomainInformation -- registrar.DomainApplication
|
||||
registrar.DomainInformation -- registrar.Contact
|
||||
registrar.DomainInformation -- registrar.Domain
|
||||
registrar.DomainInformation -- registrar.Contact
|
||||
registrar.DomainInformation *--* registrar.Contact
|
||||
|
||||
|
||||
class "registrar.Domain <Registrar>" as registrar.Domain #d6f4e9 {
|
||||
domain
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
+ name (CharField)
|
||||
+ is_active (FSMField)
|
||||
--
|
||||
}
|
||||
|
||||
|
||||
class "registrar.HostIP <Registrar>" as registrar.HostIP #d6f4e9 {
|
||||
host ip
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
+ address (CharField)
|
||||
~ host (ForeignKey)
|
||||
--
|
||||
}
|
||||
registrar.HostIP -- registrar.Host
|
||||
|
||||
|
||||
class "registrar.Host <Registrar>" as registrar.Host #d6f4e9 {
|
||||
host
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
+ name (CharField)
|
||||
~ domain (ForeignKey)
|
||||
--
|
||||
}
|
||||
registrar.Host -- registrar.Domain
|
||||
|
||||
|
||||
class "registrar.UserDomainRole <Registrar>" as registrar.UserDomainRole #d6f4e9 {
|
||||
user domain role
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
~ user (ForeignKey)
|
||||
~ domain (ForeignKey)
|
||||
+ role (TextField)
|
||||
--
|
||||
}
|
||||
registrar.UserDomainRole -- registrar.User
|
||||
registrar.UserDomainRole -- registrar.Domain
|
||||
|
||||
|
||||
class "registrar.DomainInvitation <Registrar>" as registrar.DomainInvitation #d6f4e9 {
|
||||
domain invitation
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
+ email (EmailField)
|
||||
~ domain (ForeignKey)
|
||||
+ status (FSMField)
|
||||
--
|
||||
}
|
||||
registrar.DomainInvitation -- registrar.Domain
|
||||
|
||||
|
||||
class "registrar.Nameserver <Registrar>" as registrar.Nameserver #d6f4e9 {
|
||||
nameserver
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
+ name (CharField)
|
||||
~ domain (ForeignKey)
|
||||
~ host_ptr (OneToOneField)
|
||||
--
|
||||
}
|
||||
registrar.Nameserver -- registrar.Domain
|
||||
registrar.Nameserver -- registrar.Host
|
||||
|
||||
|
||||
class "registrar.PublicContact <Registrar>" as registrar.PublicContact #d6f4e9 {
|
||||
public contact
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
+ contact_type (CharField)
|
||||
+ name (TextField)
|
||||
+ org (TextField)
|
||||
+ street1 (TextField)
|
||||
+ street2 (TextField)
|
||||
+ street3 (TextField)
|
||||
+ city (TextField)
|
||||
+ sp (TextField)
|
||||
+ pc (TextField)
|
||||
+ cc (TextField)
|
||||
+ email (TextField)
|
||||
+ voice (TextField)
|
||||
+ fax (TextField)
|
||||
+ pw (TextField)
|
||||
--
|
||||
}
|
||||
|
||||
|
||||
class "registrar.User <Registrar>" as registrar.User #d6f4e9 {
|
||||
user
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ password (CharField)
|
||||
+ last_login (DateTimeField)
|
||||
+ is_superuser (BooleanField)
|
||||
+ username (CharField)
|
||||
+ first_name (CharField)
|
||||
+ last_name (CharField)
|
||||
+ email (EmailField)
|
||||
+ is_staff (BooleanField)
|
||||
+ is_active (BooleanField)
|
||||
+ date_joined (DateTimeField)
|
||||
+ phone (PhoneNumberField)
|
||||
# groups (ManyToManyField)
|
||||
# user_permissions (ManyToManyField)
|
||||
# domains (ManyToManyField)
|
||||
--
|
||||
}
|
||||
registrar.User *--* registrar.Domain
|
||||
|
||||
|
||||
class "registrar.Website <Registrar>" as registrar.Website #d6f4e9 {
|
||||
website
|
||||
--
|
||||
+ id (BigAutoField)
|
||||
+ created_at (DateTimeField)
|
||||
+ updated_at (DateTimeField)
|
||||
+ website (CharField)
|
||||
--
|
||||
}
|
||||
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
</details>
|
1
docs/architecture/diagrams/models_diagram.svg
Normal file
1
docs/architecture/diagrams/models_diagram.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 68 KiB |
Loading…
Add table
Add a link
Reference in a new issue