wevisdemo / promise-tracker

Thai politicians and parties promise tracker
https://promisetracker.wevis.info
13 stars 5 forks source link

[other] Data preparation #15

Closed Th1nkK1D closed 2 years ago

Th1nkK1D commented 2 years ago
mixth commented 2 years ago

Here is my proposal for major data structures.

Data structure

Promises

interface Promise {
    id: number;
    isActive: boolean;
    party: string;
    category: 'equality'|'security'|'foreign'|'administration'|'culture'|'economics'|'environmental';
    status: 'inaction'|'proposed'|'paused'|'working'|'done';
    description: string; // with possible `\n`
    isNCPO: boolean;
    imageFileName?: string;
    links: {
        name: string;
        url: string;
    }[];
    timelines: {
        label: string;
        from: string; // in ISO format e.g. 2021-01 or 2021-01-15
        to?: string; // Optional; timeline can be a range or a date
    }[];
}

Concerns

Example

[
    {
        "id": 1,
        "isActive": true,
        "party": "พลังประชารัฐ",
        "category": "equality",
        "status": "done",
        "description": "เป็นโครงการที่ต่อยอดจากที่ทำไว้หนึ่งในโครงการสำคัญของรัฐบาลพลเอกประยุทธ์ จันทร์โอชา คือ โครงการ National e-payment มีโครงการย่อย “โครงการลงทะเบียนเพื่อสวัสดิการแห่งรัฐ” เพื่อฐานข้อมูลสำหรับการจัดสวัสดิการของหน่วยงานภาครัฐให้กับผู้ที่มีรายได้น้อยที่ต้องการความช่วยเหลือจากภาครัฐ ให้เงินคนทำงานรายได้ต่ำกว่า 30,000 บาทต่อปี (เส้นยากจน)\nเนื่องจากมองว่าที่ผ่านมาการจัดสวัสดิการสังคมและการให้เงินช่วยเหลือของภาครัฐยังมีข้อจำกัด โดยการจัดสรรเงินไม่ตรงกลุ่มเป้าหมาย เพราะข้อมูลยังกระจัดกระจาย และไม่พบข้อมูลเชิงลึก ดังนั้นโครงการขึ้นมาเพื่อเป็นฐานข้อมูลและให้ความช่วยเหลือได้\nนโยบายนี้เป็นหนึ่งในมาตรการช่วยเหลือในมาตรการสวัสดิการแห่งรัฐ ซึ่งอยู่ภายใต้โครงการ National e-Payment  ของรัฐบาล โดยจะมีการลงทะเบียนเพื่อรับบัตรสวัสดิการแห่งรัฐ หรือบัตรคนจน โดย 1 ในคุณสมบัติของผู้ถือบัตร คือจะต้องมีรายได้ต่ำกว่า 100,000 บาท/ปี และแบ่งย่อยออกเป็น ผู้มีสิทธิที่มีรายได้ไม่เกินกว่า 30,000 บาท/ปี จะได้รับวงเงินค่าซื้อสินค้าอุปโภคบริโภคที่จำเป็น 300 บาท/คน/เดือน ซึ่งที่ผ่านมาทางรัฐบาลมีการโอนเงินผ่านบัตรนี้แล้ว รวมถึงมีเงินเยียวยาผู้ได้รับผลกระทบจากโควิด-19เพิ่มเติมอีก",
        "isNCPO": false,
        "imageFileName": "พลังประชารัฐ_7.jpg",
        "links": [
            { "name": "ตรวจสอบสิทธิ์สวัสดิการแห่งรัฐ", "url": "https://govwelfare.cgd.go.th/welfare/check" },
            { "name": "บทความข้อมูลเกี่ยวกับบัตรสวัสดิการแห่งรัฐ", "url": "https://spm.thaigov.go.th/FILEROOM/spm-thaigov/DRAWER004/GENERAL/DATA0000/00000438.PDF" },
            { "name": "มาตรการช่วยเหลือผู้มีรายได้น้อย ในรัฐบาลประยุทธ์ - กรุงเทพธุรกิจ", "url": "https://www.bangkokbiznews.com/news/887110" },
        ],
        "timelines": [
            { "label": "เปิดโอกาสให้ผู้มีรายได้น้อยลงทะเบียน", "from": "2016-04-03", "to": "2016-05-15" },
            { "label": "เริ่มแจกบัตรสวัสดิการแห่งรัฐ", "from": "2017-09-21" }
        ]
    }
]

Parties

Parties are needed to in term of list (for filtering Promises) and to summarize on the front page. Simple list like this one should be sufficient.

interface Party {
   name: string;
   side: 'government' | 'opposition';
};

Example

[
    {
    "name": "ครูไทยเพื่อประชาชน",
        "side": "government"
    },
    {
        "name": "ก้าวไกล",
        "side": "opposition"
    }
]
Th1nkK1D commented 2 years ago

Look good to me! I actually add enum for category and status in /constants/promise as PromiseCategory and PromiseStatus which can be imported and used here. Maybe the government side can turn into an enum as well.

And I will update the status inaction to nodata according to the discussion with the designer and PM

I suggested extracting Link and Timeline out as separated interfaces so it can be used without concerning Promise

Thank you krub

Th1nkK1D commented 2 years ago

@mixth I already add your propose types in /models (previously /constants) and example data in /data do you want to implement the fetching scripts?

mixth commented 2 years ago

@Th1nkK1D Sure! I'll be implementing this in node.js env this time.

mixth commented 2 years ago

Using yarn fetch-data will update data from remote CSVs to ./data/parties.json and ./data/promises.json. These two have been populated with current data.

Remaining tasks:

Th1nkK1D commented 2 years ago

Sorry for the inconvenience. I asked PM to used the enum value in the google sheet but you finish the script first. That's means maps for topics and statuses are not necessary. Actually, the script is now broken 🙏🏼 😢

const topics = new Map<string, PromiseTopic>([
  ['บริหารจัดการ(ราชการ)', PromiseTopic.Administration],
  ['ศาสนาและวัฒนธรรม', PromiseTopic.Culture],
  ['เศรษฐกิจ', PromiseTopic.Economics],
  ['สิ่งแวดล้อม', PromiseTopic.Environmental],
  ['ความเท่าเทียม/คุณภาพชีวิต', PromiseTopic.Equality],
  ['ความมั่นคง/ปกป้องสถาบันกษัตริย์', PromiseTopic.Foreign],
  ['ต่างประเทศ', PromiseTopic.Security],
]);

function mapTopic(value: string): PromiseTopic {
  const topic = topics.get(value);
  if (topic) {
    return topic;
  }
  throw new Error(`Cannot find topic to map "${value}"`);
}

const statuses = new Map<string, PromiseStatus>([
  ['nodata', PromiseStatus.NoData],
  ['proposed', PromiseStatus.Proposed],
  ['paused', PromiseStatus.Paused],
  ['working', PromiseStatus.Working],
  ['done', PromiseStatus.Done],
]);

function mapStatus(value: string): PromiseStatus {
  const status = statuses.get(value);
  if (status) {
    return status;
  }
  throw new Error(`Cannot find status to map "${value}"`);
}

Anyway, what is your goal for the statuses map since it map to the same value 'nodata' === PromiseStatus.NoData. If you want to validate it you can transform the enum to array and check using array.includes https://stackoverflow.com/questions/43804805/check-if-value-exists-in-enum-in-typescript

Th1nkK1D commented 2 years ago

One more point, the designer and PM agree on changing category to topic to keep in all consistency.

mixth commented 2 years ago

@Th1nkK1D Those mappings are my attempt to map string to Promise* enums without forcing their types. But I can see that they are too redundant over existing maps. Changes done!

I did update:

Th1nkK1D commented 2 years ago

@mixth Since we are moving to NocoDB for the promise's image, should we rename imageFileName to imageUrl instead? Then @palminister can use it as an absolute URL with image src directly.

mixth commented 2 years ago

@Th1nkK1D imageUrl should do. I will try to close this issue by Wednesday.

mixth commented 2 years ago

Pipeline has been updated. Thanks everyone! This is considered done. 🥳