HackerNews news fetcher
newsUrl → newsURL, same for idsUrl.
const syncInterval = 30 * time.Minute is more readable. You can also convert everything that represents a time into a time.Duration or a time.Time, rather than deal with Unix timestamps. There are functions in the time package that do what you want to do (time.Date, time.Since, etc.).
About that, why does Fetch need to do complicated things with times, checking when was the last time it was called, etc.? Shouldn't the caller take care of this with a simple time.Ticker instead? It feels like this complexity shouldn't be there.
HackerNewsService is a weird name for an implementation. HackerNewsFetcher maybe?
Your postgres package isn't very idiomatic, which makes the callers do weird things to use it. For example, why do you have a SettingsRepository struct that doesn't contain anything? Why not simply have GetSettings as a package-level function? Same for the other empty structs of this package (HackerNewsRepository…).
It's more idiomatic to test for len(myString) == 0 rather than myString == "".
I'm not exactly sure what you're doing with lastSyncTime (this is pretty complex). Maybe add a comment for the line lastSyncTime = time.Now().Unix() - syncInterval - 1 or refactor this part?
Talking about refactor, Fetch() is way too long. Split it in sub-functions.
No need for an else after log.Fatal.
Rather than:

// fetch each news
log.Println("hacker news: " + fmt.Sprintf(newsUrl, id))


why not:
    log.Println("fetching from hacker news", fmt.Sprintf(newsUrl, i))
Using log.Fatal everywhere makes your code not very resilient. Maybe it's worth looking at "what can fail for transient reasons" (typically, database transactions…), and re-try the thing that failed a few times with exponential backoff.
There's lots of whitespace in the "what stores the data" part, which isn't very idiomatic. Empty lines in functions aren't really frequent.