Hi all!;)

I want my app to be blameable and need all data changes to be confirmed by SMS one-time-passwords.

I've made lot of research but still not sure if what I am planning makes any sense. So I am asking you for some advice!

Thanks in advance!


I put one of my objects Trucks as an example.

Trucks attributes:

  • Id, an auto increment
  • NumberPlate, e.g. "MBF5067" given by the govern authority
  • Description, e.g. "awesome Scania with elevator"
  • Operation, an INT, e.g. IN_OPERATION = 1, REPAIRED = 2

Requirements:

  • blameable - showing the whole object history e.g. all previous number plates with dates of creation and users(authors)

  • SMS One-Time-Passwords - changes to most important objects have to be confirmed before becoming effective. To keep this functionality comfortable User can confirm all changes with one SMS at the end of session.


My approach:

  • Every model/submodel = table in database

  • All attributes that can change over time will exist as submodels. So apart from Trucks I will have also NumberPlates, Descriptions and Operations models.

  • Any attribute during its "live" will be given at most 3 statuses: DRAFT (not confirmed by SMS, no affect on company), ACTIVE (effective/in force, have been confirmed by SMS) and DELETED (another attribute is confirmed)

  • Verifications model will manage sending one-time-passwords. Verifications model will have relationship models to lock up records that are being verified, in this case: VerificationsTrucks, VerificationsNumberPlates, VerificationsDescriptions and VerificationsOperations.


List of models

Trucks
TruckStatuses

NumberPlates
NumberPlatesStatuses

Descriptions
DescriptionsStatuses

Operations
OperationsStatuses

Verifications
VerificationsTrucks
VerificationsNumberPlates
VerificationsDescriptions
VerificationsOperations

Case scenario

(1) User #99 creates a Truck with following attributes:

  • plates: XY 220099
  • description: Awesome Scania with elevator
  • operation: IN_OPERATION = 1

(2)The following records are generated

Below, to make it more readable I've wrote "important" columns in capital letters.

Trucks:

+------+---------------------+-----------+
| Id   | CreatedAt           | CreatedBy |
+------+---------------------+-----------+
| 1    | 2014-06-30 10:00:00 |    99     |
+------+---------------------+-----------+

TruckStatuses:

+----+---------+----------+---------------------+-----------+
| Id | TruckId | >STATUS< |     CreatedAt       | CreatedBy |
+----+---------+----------+---------------------+-----------+
|  1 |    1    |     0    | 2014-06-30 10:00:00 |        99 |
+----+---------+----------+---------------------+-----------+

Track status equals 0 which means it is a DRAFT.


NumberPlates:

+----+---------+---------------+---------------------+-----------+
| Id | TruckId |   >NUMBER<    |      CreatedAt      | CreatedBy |
+----+---------+---------------+---------------------+-----------+
|  1 |    1    |  "XY 220099"  | 2014-06-30 10:00:00 |     99    |
+----+---------+---------------+---------------------+-----------+

Descriptions:

+----+---------+----------------------------------+---------------------+-----------+
| Id | TruckId |           >DESCRIPTION<          |      CreatedAt      | CreatedBy |
+----+---------+----------------------------------+---------------------+-----------+
| 1  |   1     |  "Awesome Scania with elevator"  | 2014-06-30 10:00:00 |    99     |
+----+---------+----------------------------------+---------------------+-----------+

Operations:

+----+---------+-------------+---------------------+-----------+
| Id | TruckId | >OPERATION< |         CreatedAt   | CreatedBy |
+----+---------+-------------+---------------------+-----------+
|  1 |    1    |      1      | 2014-06-30 10:00:00 |     99    |
+----+---------+-------------+---------------------+-----------+

All attributes below have statuses = 1 which means they are ACTIVE.

NumberPlateStatuses:

+----+---------------+----------+---------------------+-----------+
| Id | NumberPlateId | >STATUS< |      CreatedAt      | CreatedBy |
+----+---------------+----------+---------------------+-----------+
|  1 |       1       |     1    | 2014-06-30 10:00:00 |     99    |
+----+---------------+----------+---------------------+-----------+

DescriptionStatuses:

+----+---------------+----------+---------------------+-----------+
| Id | DescriptionId | >STATUS< |      CreatedAt      | CreatedBy |
+----+---------------+----------+---------------------+-----------+
|  1 |       1       |     1    | 2014-06-30 10:00:00 |     99    |
+----+---------------+----------+---------------------+-----------+

OperationStatuses:

+----+-------------+----------+---------------------+-----------+
| Id | OperationId | >STATUS< |       CreatedAt     | CreatedBy |
+----+-------------+----------+---------------------+-----------+
|  1 |      1      |     1    | 2014-06-30 10:00:00 |     99    |
+----+-------------+----------+---------------------+-----------+

As I wrote above - they are ACTIVE but it does not matter at all because main Truck record is kept as DRAFT = 0.


(3) User wants to confirm changes with SMS password. The following records will be added:

Verifications:

+------+--------+---------------------+--------------+-----------+
| Id   | Key    | ExpirationDate      | NoOfAttempts | CreatedBy |
+------+--------+---------------------+--------------+-----------+
| 1    | 728733 | 2014-06-30 10:15:00 |    0         |   99      |
+------+--------+---------------------+--------------+-----------+

VerificationsTrucks:

+------+----------------+---------+
|  Id  | VerificationId | TruckId |
+------+----------------+---------+
|   1  |       1        |    1    |
+------+----------------+---------+

(4) User receives SMS password. Types it down. If everything is fine the following records well be added:

TruckStatuses:

+------+---------+----------+---------------------+-----------+
| Id   | TruckId | >STATUS< |   CreatedAt         | CreatedBy |
+------+---------+----------+---------------------+-----------+
| 2    |    1    |     1    | 2014-06-30 10:10:00 |    99     |
+------+---------+----------+---------------------+-----------+

(5) Since now Truck exists as an ACTIVE = 1 record!


Problems:

Fields in the form does not correlate directly with fields in the models - to make my app user friendly I want to have only one form for Trucks. Because of that I need to double my work with validators. I need to declare them both in forms and models.

Complexity of work to be done in controllers - now to create complate Truck object I need to create records in more than 10 tables in DB.


Questions:

  1. Is my approach correct? What is wrong? Is it too much work to do?
  2. Should I build some supermodels which will manage the communication between models and submodels and forms?
  3. Should I somehow modify methods in main models (Truck) in order they creates objects of submodels? Does anyone have experience in any of these in Phalcon?

Thanks in advance for all your advices, thoughts, considerations or some links to useful materials!

Konrad