# Dev Documentation

This is a simple DOC file explaining the current state of the codebase and the 
future plans for it, as well as some clean code rules that we should follow 
when writing code for this project.

## Data Persistance Structure:

The [Extention](./README.md/#time-sheets-extension---wip) is going through a major restructuring of the timesheet entries, 
in order to be able to have a better control of the data and also to be able to have a 
better user experience when it comes to the timesheet entries.

This restructuring will also aid in better scalability and maintainability of the codebase and data set.

This is the old version of the timesheet storage structure:
###### Old-TimesheetEntry:
```json
{
    "id": "auto-generated",
    "workItemId": 12345,
    "userId": "azure-test\\user",
    "data": "23-03-2026",
    "horas": 2.5,
    "createdDate": "2026-03-23T10:00:00.000Z",
    "lastModifiedDate": "2026-03-23T12:00:00.000Z",
    "approved": null,
    "hiddenFromLogs": false
}
```
Current Iteration:
###### TimesheetEntry:
```json
{
    "id": "auto-generated",
    "workItemId": 12345,
    "userId": "azure-test\\user",
    "data": "23-03-2026",
    "horas": 2.5,
    "createdDate": "2026-03-23T10:00:00.000Z",
    "lastModifiedDate": "2026-03-23T12:00:00.000Z",
    "approved": null,
    "weekEntryId": 67890
}
```
###### LogEntry:
```json
{
    "id": "auto-generated",
    "timesheetEntryId": 12345,
    "userId": "azure-test\\user",
    "loggedDate": "23-03-2026",
    "oldHoras": 2.5,
    "newHoras": 3.0,
    "created_at": "2026-03-23T12:00:00.000Z"
}
 ```
###### ExtraWorkItem:
```json
{
    "id": "auto-generated",
    "workItemId": 12345,
    "userId": "azure-test\\user",
    "weekFirstDay": "2026-03-29"
}
```
###### SheetGroupEntry:
```json
{
    "id": "auto-generated",
    "userId": "azure-test\\user",
    "StartDate": "2026-03-23",
    "EndDate": "2026-03-29",
    "totalHoras": 40.0,
    "obs": "Some observations about the week",
    "locked": true,
    "state": "true"
}
```
State can be one of the following:
- **Null** = User has submitted the timesheet for approval (user can no longer edit inputs (has the option to recover the timesheet to make changes, admin can see and aprove/reject the whole week or individual WIs)
- **True** = Admin has *approved* the timesheet (admin can see but not edit, user can see but not edit), admin can regain access to the timesheet
- **False** = Admin has *rejected* the timesheet (admin can see but not edit, user can see and "grab" the timesheet again and pass it to draft state)
- Note: If a entry doesnot have an GroupEntry referenced to it then its in draft state and can be edited by the user, once the user submits the timesheet for approval a GroupEntry is created and all the entries are linked to it, then the user can no longer edit the entries until the admin approves or rejects the timesheet.
<br><br>
- When marked as **Rejected** the timesheet has to be followed by the obs field with the reason for the rejection, so the user can understand what to fix.
- When masked as *Approved** the obs field can be used to leave comments about the timesheet, but it's not mandatory.


## Clean code

I'm also refactoring the codebase to follow some clean code rules, in order to make it more readable and maintainable, 
as well as to make it easier for new developers to understand the codebase and contribute to it.

#### Rules:
- Class properties should be declared at the beginning of the class, before the constructor;
- Braces should be placed at the end of the line, not in a new line.
- Indentation should be consistent throughout the codebase, and should be on 1 tab base (4 spaces);
- For Strings, we use single quotes (');
- Spacing should be relation base;
- For functions and methods, lowerCamelCase should be used;
- For classes, UpperCamelCase should be used;
- For variables, lowerCamelCase should be used;
- The use of //region "region name" and //endregion is encouraged to separate code into sections but not enforced;
- A simple comment should be placed before each major function and method to explain what it does, to explain what it does and why it is there (not enforced but recommended); 

#### Example:
```js
class MyClass {
    private val = 0;
    private name = 0;
    //region Constructors
    constructorWithFlag(flag) {
        /* Flag checker */
        if (flag == 1) {
            this.val = 30;
            this.name = 'MyClass';
        } else {
            this.val = 40;
            this.name = '"MyClass"';
        }
    }
    
    constructor(name,val) {
        this.val = val;
        this.name = name;
    }
    //endregion
    
    myMethod(value) {
        /* check if property is set, if it is does the calculation if it is not, return null*/
        if (this.myProperty) {
            console.log(this.val);

            let val1 = this.val;
            let val2 = value;
            let val3 = val1 + val2;

            return val3;
        } else {
            console.log('"val" is not set');
            return null;
        }
    }
    
    getvalues() {
        /* return the values of the properties in our class */
        return {
            myProperty: this.myProperty,
            name: this.name
        };
    }
}
```
# BackUp Export File Structure

When Exporting data from the extension, the data is exported to a .json file, that follows a specific structure and naming sequence,
the name is as follows: `timesheet_backup_{timestamp}_v{extentionversion}_ev{exportversion}.json`, where: 
- timestamp is in the format of DD-MM-YYYY: `12-14-2026`, 
- extentionversion is the current version of the extension: `1.4.58`,
- exportversion is the version of the export format: `0.0.1`,
One example of the file name would be: `timesheet_backup_12-14-2026_v1.4.58_ev0.0.1.json`.

The contents of the file follow a slightly different format, as shown below:
#### Example:
```json
{
    "timestamp": "2026-04-15T15:08:44.476Z",
    "exportVersion": "1.0",
    "extentionVersion": "1.4.85",
    "data": {
        "EWI": [{}],
        "WIEG": [
            {
              "userId": "azure-test\\User 2",
              "StartDate": "13-04-2026",
              "EndDate": "19-04-2026",
              "totalHoras": 30,
              "locked": true,
              "id": "b4029692-66e6-4a6a-93c9-69d8a6b5cddf",
              "__etag": 5,
              "state": true,
              "obs": "Está aprovadissimo"
            }
        ],
        "WIE": [
            {
              "workItemId": 2,
              "userId": "azure-test\\user",
              "data": "14-04-2026",
              "horas": 10,
              "approved": true,
              "id": "eb2ff4b0-bf90-4e04-aa68-4478b5b33401",
              "__etag": 1
            },
            {
              "workItemId": 2,
              "userId": "azure-test\\user",
              "data": "13-04-2026",
              "horas": 10,
              "approved": true,
              "id": "ee132cc6-aad4-4442-a9e7-899de0e35ab7",
              "__etag": 1
            }
        ],
        "Logs": [
            {
              "userId": "azure-test\\User 2",
              "loggedDay": "13-04-2026",
              "created_at": "2026-04-15T09:03:12.441Z",
              "action": "approveWeek",
              "groupEntryId": "863919f0-7b32-4c51-b9bb-58c956745e0f",
              "obs": "",
              "id": "069c976f-e404-4747-adff-207f7e343914",
              "__etag": 1
            },
            {
              "workItemId": 2,
              "userId": "azure-test\\user",
              "loggedDay": "13-04-2026",
              "oldHoras": 0,
              "newHoras": 10,
              "created_at": "2026-04-14T09:56:38.416Z",
              "id": "09bc57ef-693e-471d-ab81-95d9316188fa",
              "__etag": 1
            }
        ]
    }
}
```

We store exportversion and extentionversion in the export file to be able to track the changes in the export 
format and also to be able to track the changes in the extension version, 
so we can know which version of the extension was used to export the data and which version of the export 
format was used, this will help us to maintain backward compatibility and also to be able to migrate old export files 
to new formats if needed.

Note: The export file JSON structure is only readable until 3000 lines, after that it gets compressed to occupy less space,
the extension can still read the file regardless is just a small measure to optimize file size, nothing more, this is also
not final, the limit may be bumped if we see necessary.
