Merge pull request #610 from cisagov/nmb/model-timeline-docs

Model timeline documentation
This commit is contained in:
Neil MartinsenBurrell 2023-05-25 10:39:01 -05:00 committed by GitHub
commit b62ca2e85d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 518 additions and 82 deletions

View 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.
![Data model timeline diagram](./model_timeline.svg)
<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>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

View 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
```
![Complete data models diagram](./models_diagram.svg)
<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>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 68 KiB